DeployHelper/internal/middleware/jwt.go

92 lines
2.2 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package middleware
import (
"ego/internal/serializer"
"ego/internal/util"
"ego/pkg/logger"
"net/http"
"strings"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
)
// AuthRequired 验证 JWT 的中间件
func AuthRequired() gin.HandlerFunc {
return func(c *gin.Context) {
// 获取Authorization头
authHeader := c.GetHeader("Authorization")
if authHeader == "" {
sendUnauthorized(c, "缺少认证头")
return
}
// 检查Bearer前缀
if !strings.HasPrefix(authHeader, "Bearer ") {
sendUnauthorized(c, "无效的认证格式请使用Bearer Token")
return
}
// 提取token
tokenString := strings.TrimPrefix(authHeader, "Bearer ")
if tokenString == "" {
sendUnauthorized(c, "Token不能为空")
return
}
// 验证token
claims, err := util.ValidateToken(tokenString)
if err != nil {
logger.Error(c, "Token验证失败", zap.Error(err))
sendUnauthorized(c, "Token验证失败: "+err.Error())
return
}
// 检查Redis中的token状态
redisKey := util.TokenGroup + claims.Username
val, err := util.Get(c, redisKey)
if err != nil {
logger.Error(c, "Redis验证失败",
zap.Error(err),
zap.String("redisKey", redisKey))
sendUnauthorized(c, "登录状态验证失败")
return
}
if val == "" {
logger.Warn(c, "Token已过期或已注销",
zap.String("username", claims.Username))
sendUnauthorized(c, "登录状态已过期,请重新登录")
return
}
// 验证Redis中的token是否与当前token一致
if val != tokenString {
logger.Warn(c, "Token不匹配可能存在重复登录",
zap.String("username", claims.Username))
sendUnauthorized(c, "登录状态异常,请重新登录")
return
}
// 将用户信息存储到context中
c.Set("userID", claims.ID)
c.Set("username", claims.Username)
c.Set("id", claims.ID) // 保持向后兼容
logger.Debug(c, "JWT认证成功",
zap.String("userID", claims.ID),
zap.String("username", claims.Username))
c.Next()
}
}
// sendUnauthorized 发送401未授权响应
func sendUnauthorized(c *gin.Context, message string) {
c.AbortWithStatusJSON(http.StatusUnauthorized, serializer.Response{
Code: http.StatusUnauthorized,
Msg: message,
Data: nil,
})
}