JWT(JSON Web令牌)
通过JSON形式作为Web应用中的令牌,用于在各方之间安全地将信息作为JSON对象传输,可以避免被别人篡改,以及在用户认证授权方面相对于传统Session减小了开销。
工作方式图:
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中间件
func main() {
r := gin.Default()
// 使用JWT中间件
r.Use(JWTMiddleware())
// 定义路由
r.GET("/api/user", func(c *gin.Context) {
// 从上下文中获取用户ID
userID, _ := c.Get("user_id")
c.JSON(http.StatusOK, gin.H{"user_id": userID})
})
// 启动服务器
r.Run(":8080")
}
- 在
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结构。