feat(api-gateway): admin 路由组 + BFF 路径重写 + announcements 路由 + Dockerfile 修复 + nextstep v2 文档
This commit is contained in:
49
services/api-gateway/internal/middleware/admin_role.go
Normal file
49
services/api-gateway/internal/middleware/admin_role.go
Normal file
@@ -0,0 +1,49 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/edu-cloud/api-gateway/internal/observability"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// AdminRoleMiddleware 强制校验请求者具备 admin 角色。
|
||||
//
|
||||
// 用途:保护 /api/admin/* 路由组(admin-portal 入口),拒绝非 admin 角色访问。
|
||||
// 前置条件:必须在 AuthMiddleware 之后注册,依赖 AuthMiddleware 注入的 x-user-roles 头。
|
||||
//
|
||||
// 响应规范(W1/W2 裁决):拒绝时返回 ActionState 信封,
|
||||
// 错误码 GW_FORBIDDEN,HTTP 403。
|
||||
//
|
||||
// 注意:DevMode 旁路由 AuthMiddleware 注入 x-user-roles=teacher,admin,
|
||||
// 因此 dev-token 自动通过 admin 校验,无需在此重复 DevMode 判断。
|
||||
func AdminRoleMiddleware() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
rolesHeader := c.GetHeader("x-user-roles")
|
||||
if rolesHeader == "" {
|
||||
observability.IncAuthFailure("admin_missing_roles")
|
||||
abortGW(c, http.StatusForbidden, "GW_FORBIDDEN", "missing roles header")
|
||||
return
|
||||
}
|
||||
|
||||
if !hasAdminRole(rolesHeader) {
|
||||
observability.IncAuthFailure("admin_role_required")
|
||||
abortGW(c, http.StatusForbidden, "GW_FORBIDDEN", "admin role required")
|
||||
return
|
||||
}
|
||||
|
||||
c.Next()
|
||||
}
|
||||
}
|
||||
|
||||
// hasAdminRole 判断逗号分隔的角色列表中是否包含 admin(大小写敏感)。
|
||||
// 角色列表格式示例:"teacher,admin" / "admin" / "student,parent"。
|
||||
func hasAdminRole(rolesHeader string) bool {
|
||||
for _, r := range strings.Split(rolesHeader, ",") {
|
||||
if strings.TrimSpace(r) == "admin" {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
Reference in New Issue
Block a user