Files
nl-video-api/api/middleware/auth.go
2025-08-03 00:11:15 +08:00

80 lines
1.9 KiB
Go

package middleware
import (
"nl-video-api/internal/consts"
"nl-video-api/utility/jwt"
"nl-video-api/utility/response"
"strings"
"github.com/gogf/gf/v2/net/ghttp"
)
// Auth JWT认证中间件
func Auth(r *ghttp.Request) {
// 获取Authorization头
authHeader := r.Header.Get("Authorization")
if authHeader == "" {
response.Error(r, response.CodeUnauthorized, "请提供认证令牌")
return
}
// 检查Bearer前缀
if !strings.HasPrefix(authHeader, "Bearer ") {
response.Error(r, response.CodeUnauthorized, "认证令牌格式错误")
return
}
// 提取token
tokenString := strings.TrimPrefix(authHeader, "Bearer ")
if tokenString == "" {
response.Error(r, response.CodeUnauthorized, "认证令牌不能为空")
return
}
// 解析token
claims, err := jwt.ParseToken(tokenString)
if err != nil {
response.Error(r, response.CodeTokenInvalid, "认证令牌无效")
return
}
// 将用户信息存储到上下文
r.SetCtxVar("user_id", claims.UserID)
r.SetCtxVar("username", claims.Username)
r.SetCtxVar("user_type", claims.UserType)
r.Middleware.Next()
}
// AdminAuth 管理员认证中间件
func AdminAuth(r *ghttp.Request) {
// 先执行基础认证
Auth(r)
if r.Response.Status >= 400 {
return
}
// 检查用户类型
userType := r.GetCtxVar("user_type").String()
if userType != consts.UserTypeAdmin {
response.Error(r, response.CodeForbidden, "需要管理员权限")
return
}
r.Middleware.Next()
}
// OptionalAuth 可选认证中间件(不强制要求登录)
func OptionalAuth(r *ghttp.Request) {
authHeader := r.Header.Get("Authorization")
if authHeader != "" && strings.HasPrefix(authHeader, "Bearer ") {
tokenString := strings.TrimPrefix(authHeader, "Bearer ")
if claims, err := jwt.ParseToken(tokenString); err == nil {
r.SetCtxVar("user_id", claims.UserID)
r.SetCtxVar("username", claims.Username)
r.SetCtxVar("user_type", claims.UserType)
}
}
r.Middleware.Next()
}