跳转到主内容
新派编程网 - 新潮编程理念,全新技术课堂!

ThinkPHP如何使用路由组实现权限验证_路由中间件鉴权技巧

ThinkPHP路由组必须显式绑定中间件才能实现权限控制;未绑定则无权限校验,即使路径在admin下也无法拦截未登录访问。 ThinkPHP 路由组怎么配中间件做权限控制 路由组本身不校验权限,必须显式绑定中间件;没绑定就等于裸奔,哪怕路由写在
admin/
下也拦不住未登录用户直接访问
/admin/user/delete
。 实操上,要在定义路由组时用
middleware
方法挂载鉴权中间件,不是在控制器或全局配置里“顺手加一下”:
Route::group('admin', function () { Route::get('user/list', 'Admin/User/list'); Route::post('user/delete', 'Admin/User/delete'); })->middleware('check_auth'); // ← 必须这里写
check_auth
是中间件名,需提前在
app/middleware.php
或注解中注册 中间件返回
Response
(如重定向到登录页)即中断执行,返回
null
或
$next($request)
才放行 别把中间件名写成类全路径(如
\app\middleware\Auth::class
),除非你用的是闭包或数组方式注册 为什么中间件里 $request->route() 取不到路由参数 因为中间件执行时机早于路由解析完成——
route()
返回空或默认值是正常现象,不是代码写错了。 要取 URL 中的动态段(比如
/article/123
的
123
),得从
$request->param()
拿,而不是依赖路由对象: 立即学习 “ PHP免费学习笔记(深入) ”;
public function handle($request, \Closure $next) { $id = $request->param('id'); // ← 正确:从请求参数取 // $id = $request->route()->param('id'); // ← 错误:此时 route() 还没解析完 if (!$this->hasPermission($id)) { return redirect('/403'); } return $next($request); }
所有基于路由参数的权限判断(如“只能删自己发的文章”)都得走
$request->param()
或
$request->url()
解析 如果需要完整路由信息(如当前分组名、是否在 admin 下),可用
$request->rule()
查当前匹配的路由规则 多个路由组嵌套时中间件执行顺序容易错乱 ThinkPHP 的中间件是“先进后出”压栈执行,外层组的中间件会比内层更早进入、更晚退出——这和直觉相反,导致日志打点、权限叠加逻辑容易出 bug。 比如同时给
api/
组和
api/v2/
子组都绑了
auth
和
throttle
,实际执行顺序是:
→ api/ 的 auth(先入) → api/v2/ 的 auth(再入) → api/v2/ 的 throttle(再入) → 控制器 ← api/v2/ 的 throttle(先出) ← api/v2/ 的 auth(再出) ← api/ 的 auth(最后出)
重复鉴权(如两层都 check_auth)不会报错,但可能多查一次数据库,性能白耗 想让子组跳过父组中间件?不能靠“覆盖”,得用
withoutMiddleware()
显式排除:
->withoutMiddleware(['auth'])
调试时用
trace('middleware', 'xxx')
打点,比看日志更准 中间件里 redirect() 后控制器仍执行的坑 常见错误是中间件写了
redirect()
却没
return
,结果 PHP 继续往下跑,控制器照常执行,甚至返回 200 + 页面内容,而浏览器收到的是 302 响应头 + 空体——页面白屏或状态错乱。 必须确保中间件里所有分支都有明确返回值:
public function handle($request, \Closure $next) { if (!session('user_id')) { return redirect('/login'); // ← 必须 return! } return $next($request); // ← 这个也不能少 }
漏掉
return
是 ThinkPHP 6+ 最隐蔽的权限失效原因之一 IDE 不会报错,PHP 也不会警告,但行为完全失控 如果中间件逻辑复杂,建议统一用
match
或早期 return 风格,避免嵌套太深漏写 权限逻辑越往后越容易混进业务判断,比如“编辑文章时检查是否作者”这种,已经不属于路由层该管的事——这时候该交给服务层做,而不是在中间件里拼 SQL 或调模型。

相关文章