package middleware import ( "strings" "github.com/casdoor/casdoor-go-sdk/casdoorsdk" "github.com/gofiber/fiber/v2" ) type AuthUserRole struct { Owner string `json:"owner"` Name string `json:"name"` DisplayName string `json:"displayName"` Description string `json:"description"` IsEnabled bool `json:"isEnabled"` } type AuthUserPermission struct { Owner string `json:"owner"` Name string `json:"name"` DisplayName string `json:"displayName"` Description string `json:"description"` Actions []string `xorm:"mediumtext" json:"actions"` Effect string `xorm:"varchar(100)" json:"effect"` IsEnabled bool `json:"isEnabled"` } type AuthUserInfo struct { Owner string `json:"owner"` // 组织名称 Name string `json:"name"` // 用户名 DisplayName string `json:"displayName"` // 页面显示的名称 Id string `json:"id"` // 用户唯一ID IsAdmin bool `json:"isAdmin"` // 是否是管理员 IsForbidden bool `json:"isForbidden"` // 是否被禁用 IsDeleted bool `json:"isDeleted"` // 是否被删除 Roles []AuthUserRole `json:"roles"` // 用户角色 Permissions []AuthUserPermission `json:"permissions"` // 用户权限 Groups []string `json:"groups"` // 用户群租 } func arrayMap[T any, R any](src []T, f func(T) R) []R { dst := make([]R, len(src)) for i, v := range src { dst[i] = f(v) } return dst } // AuthMiddleware 认证中间件 // 可选参数 requiredRoles:若不为空,将检查用户角色是否包含其中之一 func AuthMiddleware(requiredRoles ...string) fiber.Handler { return func(c *fiber.Ctx) error { authHeader := c.Get("Authorization") if authHeader == "" { return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{ "code": 401, "msg": "Missing Authorization header", }) } // 解析 Bearer Token tokenString := strings.TrimPrefix(authHeader, "Bearer ") if tokenString == authHeader { return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{ "code": 401, "msg": "Invalid token format", }) } // 验证 JWT & 提取 claims claims, err := casdoorsdk.ParseJwtToken(tokenString) if err != nil { return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{ "code": 401, "msg": "Invalid or expired token", }) } userClaims := AuthUserInfo{ Owner: claims.User.Owner, Name: claims.User.Name, DisplayName: claims.User.DisplayName, Id: claims.User.Id, IsAdmin: claims.User.IsAdmin, IsForbidden: claims.User.IsForbidden, IsDeleted: claims.User.IsDeleted, Roles: arrayMap(claims.User.Roles, func(r *casdoorsdk.Role) AuthUserRole { return AuthUserRole{ Owner: r.Owner, Name: r.Name, DisplayName: r.DisplayName, Description: r.Description, IsEnabled: r.IsEnabled, } }), Permissions: arrayMap(claims.User.Permissions, func(p *casdoorsdk.Permission) AuthUserPermission { return AuthUserPermission{ Owner: p.Owner, Name: p.Name, DisplayName: p.DisplayName, Description: p.Description, Actions: append([]string{}, p.Actions...), Effect: p.Effect, IsEnabled: p.IsEnabled, } }), Groups: append([]string(nil), claims.Groups...), } // 注入用户信息 // c.Locals("user", claims) // fmt.Printf("claims: %+v\n", claims) // fmt.Printf("roles: %+v\n", claims.User.Roles[0]) // fmt.Printf("permissions: %+v\n", claims.User.Permissions[0]) c.Locals("user", &userClaims) // 检查角色(可选) if len(requiredRoles) > 0 { for _, userRole := range claims.User.Roles { authorized := false for _, r := range requiredRoles { if userRole.Name == r { authorized = true break } } if !authorized { return c.Status(fiber.StatusForbidden).JSON(fiber.Map{ "code": 403, "msg": "Forbidden: insufficient role", }) } } } return c.Next() } } func AuthGetUserInfo(c *fiber.Ctx) *AuthUserInfo { return c.Locals("user").(*AuthUserInfo) } func AuthGetUserName(c *fiber.Ctx) string { userInfo := AuthGetUserInfo(c) return userInfo.Name } func AuthIsAdmin(c *fiber.Ctx) bool { userInfo := AuthGetUserInfo(c) return userInfo.IsAdmin } // 获取角色名列表 func AuthGetRoleNameList(c *fiber.Ctx) []string { userInfo := AuthGetUserInfo(c) roleNameList := []string{} for _, r := range userInfo.Roles { if r.IsEnabled { roleNameList = append(roleNameList, r.Name) } } return roleNameList } // 获取权限名列表 func AuthGetPermissionNameList(c *fiber.Ctx) []string { userInfo := AuthGetUserInfo(c) permissionNameList := []string{} for _, p := range userInfo.Permissions { if p.IsEnabled { permissionNameList = append(permissionNameList, p.Name) } } return permissionNameList }