You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go Fiber权限中间件判断超级用户时出现路由无法匹配问题

问题分析与修复:Fiber中间件权限逻辑导致接口无法访问

问题现象

调用/api/users/1接口时返回Cannot GET /api/users/1,但移除HasPermissionMiddleware中的if !user.IsSuperuser {}代码块后,接口可正常响应。

原代码问题点

1. 中间件嵌套调用逻辑错误

在HasPermissionMiddleware内手动调用AuthMiddleware()(c)的方式存在冲突:

if authError := AuthMiddleware()(c); authError != nil {
    return authError
}

常规Fiber中间件验证通过后会调用c.Next()传递请求,若在另一个中间件内手动执行该逻辑,会导致请求提前进入后续控制器流程,与当前中间件的权限校验逻辑产生冲突,最终引发响应混乱,出现路由未匹配的错误提示。

2. 超级用户权限逻辑完全写反

原代码逻辑为非超级用户直接放行,超级用户必须校验权限,这与常规的「超级用户跳过权限校验」逻辑相悖,容易导致权限控制逻辑混乱。

修复方案

步骤1:调整中间件使用方式

将AuthMiddleware作为路由组的全局中间件,而非在HasPermissionMiddleware内手动调用:

func UserManagementRoutes(app *fiber.App) {
    // 路由组统一添加登录验证中间件
    router := app.Group("api/users", middlewares.AuthMiddleware())

    router.Get("/", controllers.GetUsersListHandler)
    router.Get("/permissions/:id", middlewares.HasPermissionMiddleware("permissions_view"), controllers.AllPermissionOfUserHandler)
    // 补充用户详情接口路由(示例)
    router.Get("/:id", middlewares.HasPermissionMiddleware("user_view"), controllers.GetUserDetailHandler)
}

步骤2:修正权限中间件逻辑

调整超级用户判断逻辑,让超级用户直接跳过权限校验,仅对非超级用户做权限检查:

func HasPermissionMiddleware(expectedPermissions ...string) fiber.Handler {
    return func(c *fiber.Ctx) error {
        user := c.Locals("user").(models.Users)
        
        // 强制要求修改初始密码
        if !user.HasChangedInitPassword {
            return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"message": "Please change the initial password first"})
        }

        // 超级用户直接放行
        if user.IsSuperuser {
            return c.Next()
        }

        // 非超级用户校验权限
        if !HasPermissions(expectedPermissions, user.Permissions) {
            joined := strings.Join(expectedPermissions, ", ")
            log.Printf("Requires %s access", joined)
            // 修正拼写错误:Insufficiant → Insufficient
            return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"message": "Insufficient permission access"})
        }

        return c.Next()
    }
}

步骤3:检查HasPermissions函数逻辑

确保函数能正确判断用户权限集合是否包含所需权限,示例逻辑参考:

// 示例:判断用户是否拥有所有所需权限
func HasPermissions(expected []string, userPermissions []string) bool {
    permissionMap := make(map[string]bool)
    for _, p := range userPermissions {
        permissionMap[p] = true
    }
    for _, p := range expected {
        if !permissionMap[p] {
            return false
        }
    }
    return true
}

内容的提问来源于stack exchange,提问作者Fahad Md Kamal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 06:34:55