使用 golang gin 实现一个前后端分离的后台管理系统,管理员分为:
- 普通管理员
- 超级管理员
超级管理员可以访问一些普通管理员没有权限访问的接口,同时即便同一个接口两种管理员都能访问,但是可以操作的资源不同。如何设计路由及中间件可以实现清晰简洁的权限管理呢?
例如,超级管理员是我的账号,而客户也能登录这个后台,即客户是普通管理员。我作为超级管理员可以看到后台所有的设备,而客户作为普通管理员只能看到自己所属的设备,且只能对自己的设备进行远程锁机,而不能对其他客户的设备进行操作。
我实在是懒得自己想了,就问了一下 DeepSeek。DeepSeek AI 给出的方案,确实比我目前用的单一的 AuthMiddleware 内同时判断角色更合理:
func SetupRouter() *gin.Engine {
r := gin.Default()
// 公共路由(登录/登出)
public := r.Group("/api")
{
public.POST("/login", loginHandler)
}
// 管理员路由组(需要认证)
auth := r.Group("/api/admin")
auth.Use(AuthMiddleware()) // 认证中间件
{
// 所有管理员通用接口
auth.GET("/profile", getProfile)
auth.POST("/posts", createPost) // 普通管理员可创建
// 超级管理员专属接口(嵌套中间件)
super := auth.Group("")
super.Use(SuperAdminMiddleware())
{
super.DELETE("/users/:id", deleteUser) // 仅超级管理员可删除用户
super.GET("/stats", getSystemStats)
}
}
return r
}
这种用法,确实没有想到
super := auth.Group("")
super.Use(SuperAdminMiddleware())
{
// ...
}
- 认证中间件(基础权限)。只校验 jwt token 的有效性。有效,则证明是可以登录管理后台的,即可以调用 /api/admin 前缀的接口。
- 超级管理员校验中间件(角色权限)。在这里面再判断角色,判断是否是超级管理员。
- 对于资源级别的权限,可能需要在每个需要控制的接口中,手动检查当前用户是否有权操作该资源,或者在服务层统一处理。例如,删除用户的操作:普通管理员只能删自己创建的,超级可以删任何。这时候,在删除的处理函数中,先获取当前用户的角色,如果是普通,检查目标用户是否是当前用户创建的,否则拒绝。
角色分类
- 普通管理员:admin
- 超级管理员:superadmin
或者衍生的角色分类
- 超级管理员: admin
- 客户账号:client
前端的菜单控制
- 客户能访问的:client。超级管理员自然也能访问。
- 超级管理员:admin
实际,可以简化为一个权限,就是 role 判断是否是超级管理员,然后,只需要标注需要检查超级管理员才能访问的菜单权限。
微信关注我哦 👍
我是来自山东烟台的一名开发者,有感兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊, 查看更多联系方式