auth.go 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. package middleware
  2. import (
  3. "strings"
  4. "github.com/casdoor/casdoor-go-sdk/casdoorsdk"
  5. "github.com/gofiber/fiber/v2"
  6. )
  7. type AuthUserRole struct {
  8. Owner string `json:"owner"`
  9. Name string `json:"name"`
  10. DisplayName string `json:"displayName"`
  11. Description string `json:"description"`
  12. IsEnabled bool `json:"isEnabled"`
  13. }
  14. type AuthUserPermission struct {
  15. Owner string `json:"owner"`
  16. Name string `json:"name"`
  17. DisplayName string `json:"displayName"`
  18. Description string `json:"description"`
  19. Actions []string `xorm:"mediumtext" json:"actions"`
  20. Effect string `xorm:"varchar(100)" json:"effect"`
  21. IsEnabled bool `json:"isEnabled"`
  22. }
  23. type AuthUserInfo struct {
  24. Owner string `json:"owner"` // 组织名称
  25. Name string `json:"name"` // 用户名
  26. DisplayName string `json:"displayName"` // 页面显示的名称
  27. Id string `json:"id"` // 用户唯一ID
  28. IsAdmin bool `json:"isAdmin"` // 是否是管理员
  29. IsForbidden bool `json:"isForbidden"` // 是否被禁用
  30. IsDeleted bool `json:"isDeleted"` // 是否被删除
  31. Roles []AuthUserRole `json:"roles"` // 用户角色
  32. Permissions []AuthUserPermission `json:"permissions"` // 用户权限
  33. Groups []string `json:"groups"` // 用户群租
  34. }
  35. func arrayMap[T any, R any](src []T, f func(T) R) []R {
  36. dst := make([]R, len(src))
  37. for i, v := range src {
  38. dst[i] = f(v)
  39. }
  40. return dst
  41. }
  42. // AuthMiddleware 认证中间件
  43. // 可选参数 requiredRoles:若不为空,将检查用户角色是否包含其中之一
  44. func AuthMiddleware(requiredRoles ...string) fiber.Handler {
  45. return func(c *fiber.Ctx) error {
  46. authHeader := c.Get("Authorization")
  47. if authHeader == "" {
  48. return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{
  49. "code": 401,
  50. "msg": "Missing Authorization header",
  51. })
  52. }
  53. // 解析 Bearer Token
  54. tokenString := strings.TrimPrefix(authHeader, "Bearer ")
  55. if tokenString == authHeader {
  56. return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{
  57. "code": 401,
  58. "msg": "Invalid token format",
  59. })
  60. }
  61. // 验证 JWT & 提取 claims
  62. claims, err := casdoorsdk.ParseJwtToken(tokenString)
  63. if err != nil {
  64. return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{
  65. "code": 401,
  66. "msg": "Invalid or expired token",
  67. })
  68. }
  69. userClaims := AuthUserInfo{
  70. Owner: claims.User.Owner,
  71. Name: claims.User.Name,
  72. DisplayName: claims.User.DisplayName,
  73. Id: claims.User.Id,
  74. IsAdmin: claims.User.IsAdmin,
  75. IsForbidden: claims.User.IsForbidden,
  76. IsDeleted: claims.User.IsDeleted,
  77. Roles: arrayMap(claims.User.Roles, func(r *casdoorsdk.Role) AuthUserRole {
  78. return AuthUserRole{
  79. Owner: r.Owner,
  80. Name: r.Name,
  81. DisplayName: r.DisplayName,
  82. Description: r.Description,
  83. IsEnabled: r.IsEnabled,
  84. }
  85. }),
  86. Permissions: arrayMap(claims.User.Permissions, func(p *casdoorsdk.Permission) AuthUserPermission {
  87. return AuthUserPermission{
  88. Owner: p.Owner,
  89. Name: p.Name,
  90. DisplayName: p.DisplayName,
  91. Description: p.Description,
  92. Actions: append([]string{}, p.Actions...),
  93. Effect: p.Effect,
  94. IsEnabled: p.IsEnabled,
  95. }
  96. }),
  97. Groups: append([]string(nil), claims.Groups...),
  98. }
  99. // 注入用户信息
  100. // c.Locals("user", claims)
  101. // fmt.Printf("claims: %+v\n", claims)
  102. // fmt.Printf("roles: %+v\n", claims.User.Roles[0])
  103. // fmt.Printf("permissions: %+v\n", claims.User.Permissions[0])
  104. c.Locals("user", &userClaims)
  105. // 检查角色(可选)
  106. if len(requiredRoles) > 0 {
  107. for _, userRole := range claims.User.Roles {
  108. authorized := false
  109. for _, r := range requiredRoles {
  110. if userRole.Name == r {
  111. authorized = true
  112. break
  113. }
  114. }
  115. if !authorized {
  116. return c.Status(fiber.StatusForbidden).JSON(fiber.Map{
  117. "code": 403,
  118. "msg": "Forbidden: insufficient role",
  119. })
  120. }
  121. }
  122. }
  123. return c.Next()
  124. }
  125. }
  126. func AuthGetUserInfo(c *fiber.Ctx) *AuthUserInfo {
  127. return c.Locals("user").(*AuthUserInfo)
  128. }
  129. func AuthIsAdmin(c *fiber.Ctx) bool {
  130. userInfo := AuthGetUserInfo(c)
  131. return userInfo.IsAdmin
  132. }
  133. // 获取角色名列表
  134. func AuthGetRoleNameList(c *fiber.Ctx) []string {
  135. userInfo := AuthGetUserInfo(c)
  136. roleNameList := []string{}
  137. for _, r := range userInfo.Roles {
  138. if r.IsEnabled {
  139. roleNameList = append(roleNameList, r.Name)
  140. }
  141. }
  142. return roleNameList
  143. }
  144. // 获取权限名列表
  145. func AuthGetPermissionNameList(c *fiber.Ctx) []string {
  146. userInfo := AuthGetUserInfo(c)
  147. permissionNameList := []string{}
  148. for _, p := range userInfo.Permissions {
  149. if p.IsEnabled {
  150. permissionNameList = append(permissionNameList, p.Name)
  151. }
  152. }
  153. return permissionNameList
  154. }