thinkphp 8 实现授权黑名单需结合 jwt 黑名单与权限中间件:认证中间件用 redis 校验 jti 黑名单(key 为 jwt:blacklist:{jti}),权限中间件动态查 auth:deny:{uid}:{permission} 缓存,命中即返回 403;禁用 file/apcu 缓存,必须使用 redis 原子操作并设置合理 ttl。

ThinkPHP 8 本身不提供内置的“授权黑名单”功能,但可通过组合 JWT 黑名单机制 + 权限中间件拦截,实现对已认证用户(如 token 有效但权限被撤回)的实时封禁。核心不是封 IP,而是封 token 或权限行为。
用 Redis 管理 JWT 黑名单(推荐)
这是最常用、最可靠的授权黑名单方式,适用于登出、密码修改、角色回收等场景:
- 签发 token 时,必须生成唯一 jti 字段(如
uniqid(true)),并存入 Redis,key 格式为jwt:blacklist:{jti} - 在 认证中间件(如
AuthToken.php)中,解析 token 后立即检查:Redis::exists('jwt:blacklist:' . $payload->jti),命中则直接抛出HttpException(401) - 登出接口或权限变更时,主动执行:
Redis::setex('jwt:blacklist:' . $jti, $ttl, 1),其中$ttl应与该 token 剩余有效期一致(如 7200 秒) - 务必使用 Redis 驱动,禁用 file/apcu 缓存——它们不支持原子操作,集群下会失效
权限级黑名单:动态拦截特定权限调用
当某用户被移除某项权限(如 user:delete),需确保后续请求无法执行,即使 token 仍有效:
- 不依赖中间件硬编码判断,而是将权限状态存于数据库或 Redis,例如:
auth:deny:{uid}:{permission},TTL 可设为 1 小时(避免频繁查库) - 在 权限中间件(如
PermissionCheck.php)中,先读取请求所需权限标识(通过路由注解@permission('xxx')或配置),再查黑名单缓存 - 若命中,返回
HttpException(403),而非静默跳过或降级处理 - 后台管理端修改权限后,应自动触发对应 key 的删除或写入,保证秒级生效
补充:避免常见误操作
以下做法看似简单,实则存在安全漏洞或性能风险:
- ❌ 在控制器里手动
if ($user->hasPermission('xxx'))再执行逻辑——绕过中间件,权限校验被跳过 - ❌ 把黑名单写进 PHP 数组或配置文件——无法热更新,且多进程下不同步
- ❌ 使用
think\facade\Cache存黑名单——底层若为 file 驱动,高并发下exists + set非原子,可能漏判 - ❌ 黑名单 key 不设 TTL——Redis 内存持续增长,且过期 token 对应的黑名单长期残留
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











