当前位置:首页 > Go > 正文

Gin框架实现JWT认证中间件(Go语言新手入门教程)

在现代Web开发中,JWT(JSON Web Token) 是一种广泛使用的身份验证机制。结合 Gin框架Go语言,我们可以轻松构建安全、高效的API服务。本教程将手把手教你如何在 Gin 框架中实现一个完整的 JWT认证中间件,即使你是编程小白也能轻松上手!

Gin框架实现JWT认证中间件(Go语言新手入门教程) Gin框架 JWT认证 中间件 Go语言 第1张

什么是JWT?

JWT 是一种开放标准(RFC 7519),用于在网络应用环境间安全地传递声明(claims)。它由三部分组成:Header(头部)、Payload(负载)和 Signature(签名)。JWT 通常用于用户登录后生成一个令牌,客户端在后续请求中携带该令牌以证明身份。

为什么使用中间件?

在 Gin 框架中,中间件(Middleware)是一种拦截请求并执行特定逻辑的函数。通过 JWT 认证中间件,我们可以在进入业务处理函数前自动验证用户身份,避免在每个路由中重复编写认证代码,提高代码复用性和安全性。

准备工作

首先,请确保你已安装 Go 环境,并初始化了一个 Go 模块项目:

go mod init my-gin-jwt-app

然后安装必要的依赖包:

go get -u github.com/gin-gonic/gingo get -u github.com/golang-jwt/jwt/v5

步骤一:定义JWT密钥和结构体

创建 main.go 文件,并定义 JWT 密钥和用户信息结构体:

package mainimport (    "time"    "github.com/golang-jwt/jwt/v5")// JWT 密钥(生产环境中应使用环境变量)var jwtKey = []byte("my_secret_key")// Claims 自定义声明结构体type Claims struct {    UserID uint   `json:"user_id"`    Email  string `json:"email"`    jwt.RegisteredClaims}

步骤二:生成JWT Token

编写一个函数用于生成 JWT Token:

func generateJWT(userID uint, email string) (string, error) {    expirationTime := time.Now().Add(24 * time.Hour)    claims := &Claims{        UserID: userID,        Email:  email,        RegisteredClaims: jwt.RegisteredClaims{            ExpiresAt: jwt.NewNumericDate(expirationTime),            IssuedAt:  jwt.NewNumericDate(time.Now()),        },    }    token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)    return token.SignedString(jwtKey)}

步骤三:编写JWT认证中间件

这是核心部分!我们将创建一个中间件函数,用于验证请求头中的 Token:

import (    "net/http"    "strings"    "github.com/gin-gonic/gin")func AuthMiddleware() gin.HandlerFunc {    return func(c *gin.Context) {        authHeader := c.GetHeader("Authorization")        if authHeader == "" {            c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{                "error": "Missing Authorization header",            })            return        }        // 期望格式: Bearer <token>        tokenString := strings.TrimPrefix(authHeader, "Bearer ")        if tokenString == authHeader {            c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{                "error": "Invalid Authorization format",            })            return        }        claims := &Claims{}        token, err := jwt.ParseWithClaims(tokenString, claims, func(token *jwt.Token) (interface{}, error) {            return jwtKey, nil        })        if err != nil || !token.Valid {            c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{                "error": "Invalid or expired token",            })            return        }        // 将用户信息存入上下文,供后续处理器使用        c.Set("userID", claims.UserID)        c.Set("email", claims.Email)        c.Next()    }}

步骤四:集成到Gin路由中

现在,我们将中间件应用到需要保护的路由上:

func main() {    r := gin.Default()    // 公开路由:用户登录    r.POST("/login", func(c *gin.Context) {        var loginInfo struct {            Email    string `json:"email"`            Password string `json:"password"`        }        if err := c.ShouldBindJSON(&loginInfo); err != nil {            c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})            return        }        // 这里应查询数据库验证用户(简化处理)        if loginInfo.Email == "user@example.com" && loginInfo.Password == "123456" {            token, _ := generateJWT(1, loginInfo.Email)            c.JSON(http.StatusOK, gin.H{"token": token})        } else {            c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid credentials"})        }    })    // 受保护的路由组    protected := r.Group("/api")    protected.Use(AuthMiddleware())    {        protected.GET("/profile", func(c *gin.Context) {            userID, _ := c.Get("userID")            email, _ := c.Get("email")            c.JSON(http.StatusOK, gin.H{                "message": "Welcome to your profile!",                "user_id": userID,                "email":   email,            })        })    }    r.Run(":8080")}

测试你的API

1. 启动服务:go run main.go
2. 使用 curl 或 Postman 发送登录请求获取 Token:
POST http://localhost:8080/login
Body: {"email": "user@example.com", "password": "123456"}
3. 使用返回的 Token 访问受保护的接口:
GET http://localhost:8080/api/profile
Header: Authorization: Bearer <your_token_here>

总结

通过本教程,你已经学会了如何在 Gin框架 中使用 Go语言 实现一个完整的 JWT认证中间件。这不仅提升了 API 的安全性,也展示了中间件在 Web 开发中的强大作用。记住,在生产环境中务必使用强密钥、HTTPS 传输,并妥善管理 Token 的有效期。

关键词:Gin框架、JWT认证、中间件、Go语言