初始化
This commit is contained in:
158
server/middleware/auth.go
Normal file
158
server/middleware/auth.go
Normal file
@@ -0,0 +1,158 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"seeyon-filesystem/repository"
|
||||
"seeyon-filesystem/utils"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// JWTAuth JWT认证中间件
|
||||
// 从请求头 Authorization: Bearer <token> 中提取并验证JWT
|
||||
// 验证通过后将用户信息存入上下文
|
||||
func JWTAuth(secret string) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
authHeader := c.GetHeader("Authorization")
|
||||
if authHeader == "" {
|
||||
utils.Unauthorized(c, "缺少Authorization请求头")
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
|
||||
parts := strings.SplitN(authHeader, " ", 2)
|
||||
if len(parts) != 2 || parts[0] != "Bearer" {
|
||||
utils.Unauthorized(c, "Authorization格式错误, 应为: Bearer <token>")
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
|
||||
claims, err := utils.ParseToken(parts[1], secret)
|
||||
if err != nil {
|
||||
utils.Unauthorized(c, "Token无效或已过期: "+err.Error())
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
|
||||
c.Set("user_id", claims.UserID)
|
||||
c.Set("username", claims.Username)
|
||||
c.Set("role", claims.Role)
|
||||
|
||||
c.Next()
|
||||
}
|
||||
}
|
||||
|
||||
// AdminAuth 管理员权限中间件
|
||||
// 检查用户是否具有admin角色(兼容旧的Role字段)
|
||||
func AdminAuth() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
role, exists := c.Get("role")
|
||||
if !exists || role.(string) != "admin" {
|
||||
utils.Forbidden(c, "需要管理员权限")
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
c.Next()
|
||||
}
|
||||
}
|
||||
|
||||
// RequirePermission 权限检查中间件
|
||||
// 基于RBAC模型, 检查用户是否拥有指定权限
|
||||
// 用法: middleware.RequirePermission("file:upload")
|
||||
func RequirePermission(permissionCode string) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
userID := GetCurrentUserID(c)
|
||||
if userID == 0 {
|
||||
utils.Unauthorized(c, "未登录")
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
|
||||
// 管理员拥有所有权限
|
||||
role, _ := c.Get("role")
|
||||
if role == "admin" {
|
||||
c.Next()
|
||||
return
|
||||
}
|
||||
|
||||
// 通过RBAC查询权限
|
||||
permRepo := repository.NewPermissionRepository()
|
||||
codes, err := permRepo.GetUserPermissionCodes(userID)
|
||||
if err != nil {
|
||||
utils.ServerError(c, "权限检查失败")
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
|
||||
for _, code := range codes {
|
||||
if code == permissionCode || code == "*" {
|
||||
c.Next()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
utils.Forbidden(c, "缺少权限: "+permissionCode)
|
||||
c.Abort()
|
||||
}
|
||||
}
|
||||
|
||||
// RequireAnyPermission 权限检查中间件(满足任一即可)
|
||||
// 用法: middleware.RequireAnyPermission("file:upload", "file:manage")
|
||||
func RequireAnyPermission(permissionCodes ...string) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
userID := GetCurrentUserID(c)
|
||||
if userID == 0 {
|
||||
utils.Unauthorized(c, "未登录")
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
|
||||
role, _ := c.Get("role")
|
||||
if role == "admin" {
|
||||
c.Next()
|
||||
return
|
||||
}
|
||||
|
||||
permRepo := repository.NewPermissionRepository()
|
||||
codes, err := permRepo.GetUserPermissionCodes(userID)
|
||||
if err != nil {
|
||||
utils.ServerError(c, "权限检查失败")
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
|
||||
codeSet := make(map[string]bool, len(codes))
|
||||
for _, code := range codes {
|
||||
codeSet[code] = true
|
||||
}
|
||||
|
||||
for _, required := range permissionCodes {
|
||||
if codeSet[required] || codeSet["*"] {
|
||||
c.Next()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
utils.Forbidden(c, "权限不足")
|
||||
c.Abort()
|
||||
}
|
||||
}
|
||||
|
||||
// GetCurrentUserID 从上下文获取当前用户ID
|
||||
func GetCurrentUserID(c *gin.Context) uint64 {
|
||||
userID, exists := c.Get("user_id")
|
||||
if !exists {
|
||||
return 0
|
||||
}
|
||||
return userID.(uint64)
|
||||
}
|
||||
|
||||
// GetCurrentUsername 从上下文获取当前用户名
|
||||
func GetCurrentUsername(c *gin.Context) string {
|
||||
username, exists := c.Get("username")
|
||||
if !exists {
|
||||
return ""
|
||||
}
|
||||
return username.(string)
|
||||
}
|
||||
Reference in New Issue
Block a user