sa-token 鉴权
Java 侧做法
Java 用 sa-token 管登录态、@SaCheckPermission 校验权限。注解写在 Controller 方法上,由 sa-token 的 AOP 切面拦截校验。
Go 侧做法
Go 用 sa-token-go(JWT + Redis 存会话) 复刻,权限校验改为 pkg/middleware 里的 鉴权中间件查权限码。
登录态
loginhelper.Login(loginUser, device)签发 token、存 token session(Redis)、双写 account session 的权限 / 角色。LoginUser存为 JSON 串(非指针),取回要json.Unmarshal。- 权限 / 角色是 account session,与 token session 的 loginUser 两套存储,必须双写,否则权限码恒判否。
超管的 *:*:*
sa-token 的 bug sa-token 对 *:*:* 前缀匹配有 bug,故 写入侧把超管权限码转成 *;但
LoginUser.MenuPermission 仍保持 *:*:* 给前端(前端按此判断是否显示全量菜单)。
权限校验语义
| 中间件 | 语义 |
|---|---|
satoken.CheckPermission("a", "b") | 多权限码 OR——任一命中放行 |
satoken.CheckRole("admin") | 需该角色 |
sagin.CheckLogin() | 仅需登录,无权限要求 |
sagin.Ignore() | 完全公开(仅在 TokenInterceptor 组内时才需要) |
多个中间件串联 = AND:CheckRole(superAdmin), CheckPermission("system:menu:list") 两个都得过。注意这与单个 CheckPermission 内部多值的 OR 语义不同。
取登录态
GetLoginUser(c) 按请求缓存进 gin.Context(一次 Redis),返回的指针是 请求内共享,调用方只读不改。
go
loginUser := loginhelper.GetLoginUser(c)
userID := loginhelper.GetUserID(c)
deptID := loginhelper.GetDeptID(c)登出 / 踢人
LogoutUser(userID)只注销 default 设备的会话。LogoutUsers([]userID)批量。
详见 pkg 参考 / satoken。