Files
IUQT/userAuthCenter/biz/router/auth/middleware.go
2025-08-04 18:15:14 +08:00

100 lines
2.9 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.

// Code generated by hertz generator.
package auth
import (
"context"
"errors"
"fmt"
"github.com/cloudwego/hertz/pkg/app"
"github.com/cloudwego/hertz/pkg/common/hlog"
"net/http"
"userAuthCenter/biz/dal/redis"
"userAuthCenter/biz/utils"
)
func rootMw() []app.HandlerFunc {
// your code...
return nil
}
func _authMw() []app.HandlerFunc {
// your code...
return nil
}
func _loginMw() []app.HandlerFunc {
// your code...
return nil
}
func _logoutMw() []app.HandlerFunc {
// your code...
return nil
}
func _refreshMw() []app.HandlerFunc {
// your code...
return nil
}
// AuthMiddleware Hertz鉴权中间件验证请求中的令牌有效性
// 参数tokenStore - 令牌存储管理器Redis操作封装
func AuthMiddleware(tokenStore *redis.TokenStore) app.HandlerFunc {
return func(ctx context.Context, c *app.RequestContext) {
// 1. 从请求头获取令牌默认使用Authorization: Bearer {token}格式)
authHeader := c.Request.Header.Get("Authorization")
if authHeader == "" {
hlog.Warn("请求头缺少Authorization")
c.AbortWithStatusJSON(http.StatusUnauthorized, fmt.Sprintf("请登录"))
return
}
// 2. 解析Bearer令牌格式"Bearer {token}"
token, err := parseBearerToken(authHeader)
if err != nil {
hlog.Warnf("令牌格式错误: %v", err)
c.AbortWithStatusJSON(http.StatusUnauthorized, fmt.Sprintf("令牌格式错误"))
return
}
// 3. 验证JWT令牌本身的有效性签名、过期时间等
claims, err := utils.ValidateToken(token)
if err != nil {
hlog.Warnf("JWT令牌无效: %v", err)
c.AbortWithStatusJSON(http.StatusUnauthorized, fmt.Sprintf("令牌无效或已过期"))
return
}
// 4. 检查令牌在Redis中的状态是否被拉黑、是否属于当前用户
isValid, err := tokenStore.IsTokenValid(ctx, claims.Username, token)
if err != nil {
hlog.Errorf("Redis验证令牌失败: %v", err)
c.AbortWithStatusJSON(http.StatusInternalServerError, fmt.Sprintf("令牌验证失败"))
return
}
if !isValid {
hlog.Warnf("令牌已失效: username=%s, token=%s", claims.Username, token)
c.AbortWithStatusJSON(http.StatusUnauthorized, fmt.Sprintf("令牌已失效"))
return
}
// 5. 令牌验证通过,将用户信息存入上下文供后续处理使用
c.Set("userID", claims.UserID) // 存储用户ID
c.Set("username", claims.Username) // 存储用户名
c.Set("roles", claims.Roles) // 存储用户角色(如果需要权限控制)
// 继续处理后续请求
c.Next(ctx)
}
}
// parseBearerToken 从Authorization头中解析出令牌处理"Bearer {token}"格式)
func parseBearerToken(authHeader string) (string, error) {
const bearerPrefix = "Bearer "
if len(authHeader) < len(bearerPrefix) || authHeader[:len(bearerPrefix)] != bearerPrefix {
return "", errors.New("令牌格式错误")
}
return authHeader[len(bearerPrefix):], nil
}