package middleware import ( "fmt" "github.com/gin-gonic/gin" "icloudapp.cn/tools/entity" "icloudapp.cn/tools/service" "net/http" "strings" ) // 基于JWT认证的中间件 验证token的中间件 func JWTAuthMiddleware() func(c *gin.Context) { return func(ctx *gin.Context) { //携带Token有三种方式 //1.放在请求头 //2.放在请求体 //3.放在URI //这里实现的方法是Token放在header的Authorization,并使用Bearer开头 authHeader := ctx.Request.Header.Get("Authorization") //获取请求中头部的token cookie, _ := ctx.Cookie("poster_sid") if authHeader == "" && cookie != "" { authHeader = "Bearer " + cookie } if authHeader == "" { ctx.JSON(http.StatusOK, gin.H{ "code": entity.CodeAuthIsNull, "msg": entity.CodeAuthIsNull.Msg(), }) ctx.Abort() //授权失败,调用Abort以确保没有调用此请求的其余处理程序 return } parts := strings.SplitN(authHeader, " ", 2) if !(len(parts) == 2 && parts[0] == "Bearer") { ctx.JSON(http.StatusOK, gin.H{ "code": entity.CodeInvalidToken, "msg": entity.CodeInvalidToken.Msg(), }) ctx.Abort() return } posterClaim, err := service.ParseJWTToken(parts[1]) if err != nil { ctx.JSON(http.StatusOK, gin.H{ "code": entity.CodeTokenExpired, "msg": entity.CodeTokenExpired.Msg(), }) ctx.Abort() return } //token 和 redis 中保存的不匹配,也验证失败 token := service.GetJWTTokenFromRedis(posterClaim.Uid) if token == "" || token != parts[1] { ctx.JSON(http.StatusOK, gin.H{ "code": entity.CodeAuthFail, "msg": entity.CodeAuthFail.Msg(), }) ctx.Abort() return } //将当前请求的username信息保存到请求的上下文c ctx.Set("jwt_uid", posterClaim.Uid) ctx.Set("jwt_username", posterClaim.Username) //设置Request参数 ctx.AddParam("jwt_uid", fmt.Sprint(posterClaim.Uid)) ctx.AddParam("jwt_username", posterClaim.Username) ctx.Next() } }