Gin框架中使用JWT|青训营

94 阅读2分钟

JWT(JSON Web令牌)

通过JSON形式作为Web应用中的令牌,用于在各方之间安全地将信息作为JSON对象传输,可以避免被别人篡改,以及在用户认证授权方面相对于传统Session减小了开销。

工作方式图:JWT认证 | Light文档

Gin框架中使用JWT可以提供身份验证和授权功能。

1. 导入依赖

首先,导入需要的依赖包:

import (
	"github.com/gin-gonic/gin"
	"github.com/dgrijalva/jwt-go"
	"time"
)
  • gin:Gin框架的主要依赖包。
  • jwt-go:JWT的Go语言实现。

2. 定义JWT中间件

func JWTMiddleware() gin.HandlerFunc {
	return func(c *gin.Context) {
		tokenString := c.GetHeader("Authorization")
		if tokenString == "" {
			c.JSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized"})
			c.Abort()
			return
		}
 
		token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
			return []byte("secret"), nil
		})
 
		if err != nil || !token.Valid {
			c.JSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized"})
			c.Abort()
			return
		}
 
		claims, ok := token.Claims.(jwt.MapClaims)
		if !ok {
			c.JSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized"})
			c.Abort()
			return
		}
 
		c.Set("user_id", claims["user_id"])
 
		c.Next()
	}
}
  • JWTMiddleware是一个Gin中间件函数,用于验证JWT令牌。它会在每个请求到达处理器之前被调用。
  • 首先,从请求的Header中获取Authorization字段的值,该字段应为以"Bearer "开头的JWT令牌。
  • 如果令牌为空,则返回未授权的错误响应,并中断请求处理。
  • 使用jwt.Parse方法解析JWT令牌,传入的回调函数用于验证签名。这里的示例中,使用了一个固定的字符串作为签名验证的密钥,实际使用时应该使用更安全的方式存储和获取密钥。
  • 如果解析出错或令牌无效,则返回未授权的错误响应,并中断请求处理。
  • 如果解析成功,将令牌中的用户ID存储到Gin的上下文中,以便后续处理器可以使用。
  • 最后,调用c.Next()继续执行后续的处理器。

3. 使用JWT中间件

  1. func main() {
  2. r := gin.Default()
  3. // 使用JWT中间件
  4. r.Use(JWTMiddleware())
  5. // 定义路由
  6. r.GET("/api/user", func(c *gin.Context) {
  7. // 从上下文中获取用户ID
  8. userID, _ := c.Get("user_id")
  9. c.JSON(http.StatusOK, gin.H{"user_id": userID})
  10. })
  11. // 启动服务器
  12. r.Run(":8080")
  13. }
  • main函数中,创建一个默认的Gin引擎。
  • 使用r.Use(JWTMiddleware())将JWT中间件添加到全局中间件链中,以便对所有请求进行JWT验证。
  • 定义了一个GET请求的处理器,路径为/api/user。在处理器内部,可以通过c.Get("user_id")来获取之前在中间件中存储的用户ID。
  • 最后,调用r.Run(":8080")启动Gin服务器。

这样,当请求到达/api/user路径时,会先经过JWT中间件进行JWT验证。如果验证通过,处理器会返回用户ID的JSON响应;如果验证失败,处理器会返回未授权的错误响应。

以上只是实现了jwt的简单功能,方便理解。在实际的项目中,应该使用更加完善的demo结构。