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

221 lines
4.7 KiB
Go

package middleware
import (
"strings"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp"
"nl-video-api/internal/service/auth"
"nl-video-api/utility/jwt"
"nl-video-api/utility/response"
)
// PermissionMiddleware 权限验证中间件
func PermissionMiddleware(r *ghttp.Request) {
// 获取请求路径和方法
apiPath := r.URL.Path
method := r.Method
// 跳过不需要权限验证的路径
skipPaths := []string{
"/api/v1/auth/login",
"/api/v1/auth/register",
"/api/v1/admin/login",
"/api/v1/admin/register",
}
for _, skipPath := range skipPaths {
if apiPath == skipPath {
r.Middleware.Next()
return
}
}
// 获取Token
token := r.Header.Get("Authorization")
if token == "" {
response.Error(r, 1002, "请先登录")
return
}
// 移除Bearer前缀
if strings.HasPrefix(token, "Bearer ") {
token = strings.TrimPrefix(token, "Bearer ")
}
// 验证Token
claims, err := jwt.ParseToken(token)
if err != nil {
response.Error(r, 1003, "Token无效")
return
}
// 获取用户ID
userId := int(claims.UserID)
if userId <= 0 {
response.Error(r, 1003, "Token无效")
return
}
// 检查API权限
hasPermission, err := auth.Permission.CheckApiPermission(r.Context(), userId, apiPath, method)
if err != nil {
g.Log().Errorf(r.Context(), "权限检查失败: %v", err)
response.Error(r, 1004, "权限检查失败")
return
}
if !hasPermission {
response.Error(r, 1004, "没有访问权限")
return
}
// 将用户ID存储到上下文中
r.SetCtxVar("user_id", userId)
r.Middleware.Next()
}
// RolePermissionMiddleware 角色权限验证中间件
func RolePermissionMiddleware(requiredRole string) func(r *ghttp.Request) {
return func(r *ghttp.Request) {
// 获取Token
token := r.Header.Get("Authorization")
if token == "" {
response.Error(r, 1002, "请先登录")
return
}
// 移除Bearer前缀
if strings.HasPrefix(token, "Bearer ") {
token = strings.TrimPrefix(token, "Bearer ")
}
// 验证Token
claims, err := jwt.ParseToken(token)
if err != nil {
response.Error(r, 1003, "Token无效")
return
}
// 获取用户角色
userRole := claims.UserType
if userRole == "" {
response.Error(r, 1004, "用户角色信息无效")
return
}
// 检查角色权限
if userRole != requiredRole && userRole != "super_admin" {
response.Error(r, 1004, "没有访问权限")
return
}
r.Middleware.Next()
}
}
// AdminPermissionMiddleware 管理员权限验证中间件
func AdminPermissionMiddleware(r *ghttp.Request) {
// 获取Token
token := r.Header.Get("Authorization")
if token == "" {
response.Error(r, 1002, "请先登录")
return
}
// 移除Bearer前缀
if strings.HasPrefix(token, "Bearer ") {
token = strings.TrimPrefix(token, "Bearer ")
}
// 验证Token
claims, err := jwt.ParseToken(token)
if err != nil {
response.Error(r, 1003, "Token无效")
return
}
// 检查是否为管理员Token
userType := claims.UserType
if userType != "admin" {
response.Error(r, 1004, "需要管理员权限")
return
}
// 获取管理员ID
adminId := int(claims.UserID)
if adminId <= 0 {
response.Error(r, 1003, "Token无效")
return
}
// 将管理员ID存储到上下文中
r.SetCtxVar("admin_id", adminId)
r.Middleware.Next()
}
// CheckPermissionCode 检查权限编码中间件
func CheckPermissionCode(permissionCode string) func(r *ghttp.Request) {
return func(r *ghttp.Request) {
// 获取用户ID
userId := r.GetCtxVar("user_id")
if userId == nil {
response.Error(r, 1002, "请先登录")
return
}
userIdInt := userId.Int()
if userIdInt <= 0 {
response.Error(r, 1002, "用户信息无效")
return
}
// 检查权限
hasPermission, err := auth.Permission.CheckUserPermission(r.Context(), userIdInt, permissionCode)
if err != nil {
g.Log().Errorf(r.Context(), "权限检查失败: %v", err)
response.Error(r, 1004, "权限检查失败")
return
}
if !hasPermission {
response.Error(r, 1004, "没有访问权限")
return
}
r.Middleware.Next()
}
}
// SuperAdminMiddleware 超级管理员权限验证中间件
func SuperAdminMiddleware(r *ghttp.Request) {
// 获取Token
token := r.Header.Get("Authorization")
if token == "" {
response.Error(r, 1002, "请先登录")
return
}
// 移除Bearer前缀
if strings.HasPrefix(token, "Bearer ") {
token = strings.TrimPrefix(token, "Bearer ")
}
// 验证Token
claims, err := jwt.ParseToken(token)
if err != nil {
response.Error(r, 1003, "Token无效")
return
}
// 检查是否为超级管理员
role := claims.UserType
if role != "super_admin" {
response.Error(r, 1004, "需要超级管理员权限")
return
}
r.Middleware.Next()
}