如何实现类似GitHub的细粒度个人访问令牌功能?
细粒度权限令牌的实现思路
一、GitHub细粒度PAT的底层逻辑
- GitHub生成细粒度PAT时,不会生成包含权限/有效期的JWT返回给用户。用户拿到的
github_pat_<randomString>是一个不透明令牌,本身不携带任何可解析的权限信息。 - 后端会将这个随机令牌与对应的权限范围、有效期、关联用户、资源限制(比如只能访问特定仓库)等元数据绑定,存储在数据库中,令牌本身只是一个映射键。
二、核心实现方案
1. 令牌生成与存储
- 生成足够长的随机字符串作为令牌(比如32位以上的随机字符,可自定义前缀如
your_app_pat_),确保不可猜测。 - 存储时,不要直接存明文令牌,要对令牌做哈希处理(比如用bcrypt或Argon2),只存哈希值。同时关联存储:用户ID、权限列表(如
repo:read、user:email)、有效期、资源限制(如特定项目ID)、创建时间、最后使用时间等。
2. 权限校验流程
- 当用户用令牌请求API时,后端先提取令牌,对其做哈希后在数据库中查找对应的元数据。
- 校验令牌是否过期,再检查当前请求的接口/资源是否在令牌的权限范围内。
- 可选:记录令牌的使用日志,用于审计和异常检测(比如异地登录、高频请求)。
3. 令牌生命周期管理
- 支持用户主动撤销令牌,后端标记对应元数据为失效状态。
- 自动清理过期令牌:定时任务扫描数据库,删除已过期的令牌哈希和元数据。
- 提供令牌列表页面,让用户查看自己的令牌权限、有效期,支持编辑(比如调整权限)或重新生成令牌。
4. 安全增强
- 令牌生成后只显示一次,用户需要自行保存,后端不再存储明文令牌。
- 支持权限最小化:让用户选择具体的权限范围(比如仅允许访问某个项目的只读权限),而非全量权限。
- 可选:添加IP限制,只允许特定IP段使用令牌;或者绑定设备指纹,提升安全性。
三、为什么不优先用JWT?
JWT是自包含令牌,优点是无需查库即可校验,但缺点在细粒度权限场景下更突出:
- 权限一旦下发,无法中途修改,除非重新生成令牌。
- 令牌本身包含权限信息,虽签名不可篡改,但用户可解析出权限范围,存在信息泄露风险。
- 无法主动撤销令牌,只能等过期,除非维护黑名单,但这样就失去了JWT无需查库的优势。
而不透明令牌更适合细粒度权限场景,后端可灵活调整权限、主动撤销,安全性更高。
内容的提问来源于stack exchange,提问作者Andy
相关产品推荐
相关产品推荐

