Skip to content

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 组内时才需要)

多个中间件串联 = ANDCheckRole(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

基于 MIT 协议开源