← 返回博客
go2026-09-12 22:37:561 分钟 · 411 0

Gin 权限控制:用 casbin 做 RBAC

用 casbin 在 Gin 里落地 RBAC,讲清 model/policy 定义、中间件按角色鉴权,以及与第 6 篇 JWT 的认证衔接。

#gin#权限控制#casbin

1. 认证和授权是两件事

第 6 篇的 JWT 解决「你是谁」(认证)。这一篇解决「你能干啥」(授权)。登录用户不一定能删文章,要按角色判断。

2. casbin 模型

model.conf 定义 RBAC 规则:

[request_definition]
r = sub, obj, act
[policy_definition]
p = sub, obj, act
[matchers]
m = r.sub == p.sub && r.obj == p.obj && r.act == p.act

sub 是角色/用户,obj 是资源(如 /articles),act 是操作(get/delete)。

3. policy 是具体授权

p, admin, /articles, delete
p, admin, /users, *
p, editor, /articles, post

admin 能删文章、管用户;editor 只能发文章。改权限只改 policy,不动代码。

4. 中间件鉴权

func Casbin(e *casbin.Enforcer) gin.HandlerFunc {
    return func(c *gin.Context) {
        role := c.GetString("role") // 来自第 6 篇 JWT 解析
        ok, _ := e.Enforce(role, c.FullPath(), strings.ToLower(c.Request.Method))
        if !ok {
            c.JSON(403, gin.H{"error": "无权限"})
            c.Abort()
            return
        }
        c.Next()
    }
}

JWT 中间件先跑填 role,casbin 再判断,两层串起来。

5. 和 JWT 衔接

登录时把角色写进 JWT claims(第 6 篇),鉴权中间件解出来当 sub

claims := &Claims{}
jwt.ParseWithClaims(token, claims, keyFunc)
c.Set("role", claims.Role)

别在前端存角色当真理,每次请求服务端按 token 里的角色判,防伪造提权。

6. 动态权限

policy 存库,后台改了实时加载:

e.LoadPolicy() // 改完重读
e.AddPolicy("viewer", "/articles", "get") // 或直接加一条

小系统用文件 policy 够了,多租户/复杂权限存库 + 缓存。

7. 上线清单

认证(JWT)和授权(casbin)分开,别混。角色从 JWT claims 取,不自前端传。policy 改完重加载,动态权限走库。默认拒绝(没匹配到 policy 就 403),别默认放行。超级管理员和白名单接口单独处理,避免被 RBAC 误伤。

四篇走完,第四季把文档、性能、数据库、权限这四个生产必补的坑填上了。三季加这一季,Gin 后端从能写到能上线到能扛量到能管权限,齐了。

相关推荐

本文为原创文章,采用CC BY-NC-SA 4.0协议授权,转载请保留署名与原文链接。原文链接:https://www.wxbuluo.com/article/208