thinkphp 6.x 移除了内置 auth 类,推荐用中间件实现鉴权:路由级 rbac 校验需映射路由名到权限、jwt/oauth2 应复用成熟库解析 token 并挂载到 request,同时注意 cli 绕过和多守卫切换。

ThinkPHP 6.x 中为什么不用 Auth 而该用 think-auth 或自建中间件
ThinkPHP 官方从 6.0 开始移除了内置的 Auth 类(即 TP5 的 think\Auth),所以直接 require 或 new Auth 会报 Class "think\Auth" not found。社区维护的 think-auth 库虽可接入,但它基于 RBAC 且强耦合数据库结构,若你已有用户/角色/权限表,或想对接 OAuth2、JWT、CAS 等第三方鉴权服务,硬套 think-auth 反而增加转换成本。
更务实的做法是:绕过“Auth 系统集成”这个概念,直接在中间件中完成鉴权逻辑。关键不是“怎么装 Auth”,而是“在哪验、验什么、不通过怎么拦”。
如何在中间件里做路由级权限校验(RBAC 场景)
假设你已有三张表:users、roles、permissions,并已通过关联查出当前用户拥有的权限标识(如 user:edit、order:delete)。校验应发生在请求进入控制器前,且只对需要保护的路由生效。
- 新建中间件
app/middleware/PermissionCheck.php,handle()方法中获取当前路由名($request->route()->getName())或规则路径($request->url(true)) - 从 Session 或 Token 解析出用户 ID,查库得到该用户所有权限字符串数组(避免每次查完整角色树,缓存到 Redis 更稳)
- 定义权限映射表:把路由名映射到所需权限,例如
['admin.user.edit' => 'user:edit'],或用正则匹配(admin.*.delete → .*:delete) - 不匹配时调用
abort(403, 'Forbidden'),别用redirect()——中间件里跳转易丢失原始请求方法和参数
示例片段:
// 在 handle() 中
$rule = $request->route()->getName();
$allowed = $this->getPermissions($userId); // 如 ['user:list', 'user:edit']
$required = $this->getRequiredPermission($rule); // 如 'user:edit'
if (!in_array($required, $allowed)) {
abort(403);
}
对接 JWT/OAuth2 第三方鉴权时,Token 解析和刷新怎么做
如果你的前端用 Authorization: Bearer xxx 传 token,后端不该自己实现 JWT 签名校验,而应复用成熟库(如 firebase/php-jwt),重点在于:何时解析、解析结果放哪、失效了怎么处理。
- 中间件中用
$token = $request->header('authorization')提取,去掉Bearer前缀 - 用
JWT::decode()验签并捕获ExpiredException、SignatureInvalidException,对应返回 401 或 403 - 解出的 payload(如
uid、scope)建议挂到$request->attr('user', $payload),后续控制器可直接用$this->request->attr('user') - 不要在中间件里自动刷新 token:刷新需客户端主动发起
/api/token/refresh请求,且必须校验 refresh_token(通常存在 HttpOnly Cookie 或独立 header)
容易被忽略的两个边界点:多守卫切换与 CLI 命令绕过
TP6 的 auth(注意不是旧版 Auth)其实是守卫(Guard)机制,比如 admin 守卫用 session,api 守卫用 token。但很多人写中间件时默认只查 auth('api'),却忘了命令行执行 php think hello 也会走中间件——此时 $request->header() 为空,auth 守卫可能抛异常。
- 在中间件开头加判断:
if (is_cli()) { return $next($request); } - 不同模块用不同守卫时,别全局绑定一个
auth实例;应在中间件内按需调用auth('admin')->check()或auth('api')->check() - 数据库权限变更后,已登录用户的 session 或 token 不会自动失效——要么加版本号字段做强制登出,要么在每次鉴权时查一次权限缓存是否过期
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











