100 lines
2.9 KiB
Go
100 lines
2.9 KiB
Go
// 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
|
||
}
|