Laravel调用hasPermissionTo()报空对象错误求助
Call to a member function hasPermissionTo() on null错误 我在配置Spatie Laravel Permission实现角色与权限管理时,遇到了如下致命错误:
(1/1) FatalErrorException Call to a member function hasPermissionTo() on null in ClearanceMiddleware.php line 17
我的数据库权限相关表结构如下:
当前使用的ClearanceMiddleware代码如下:
<?php namespace App\Http\Middleware; use Closure; use Illuminate\Support\Facades\Auth; class ClearanceMiddleware { /** * Handle an incoming request. * * @param \Illuminate\Http\Request $request * @param \Closure $next * @return mixed */ public function handle($request, Closure $next) { if (Auth::user()->hasPermissionTo('Administer roles & permissions')) //If user has this permission { return $next($request); } if ($request->is('posts/create'))//If user is creating a post { if (!Auth::user()->hasPermissionTo('Create Post')) { abort('401'); } else { return $next($request); } } if ($request->is('posts/*/edit')) //If user is editing a post { if (!Auth::user()->hasPermissionTo('Edit Post')) { abort('401'); } else { return $next($request); } } if ($request->isMethod('Delete')) //If user is deleting a post { if (!Auth::user()->hasPermissionTo('Delete Post')) { abort('401'); } else { return $next($request); } } return $next($request); } }
问题原因分析
这个错误的核心是**Auth::user()返回了null**——也就是说,当这个中间件执行时,当前请求并没有已登录的用户,直接调用hasPermissionTo()自然会触发报错。
解决步骤
调整中间件执行顺序
Laravel的中间件是按注册顺序执行的,你的ClearanceMiddleware必须放在Authenticate(登录验证)中间件之后。打开app/Http/Kernel.php,检查$middlewareGroups里的web组,确保Authenticate中间件先于ClearanceMiddleware执行;如果是路由单独绑定中间件,也要确保路由同时绑定了auth中间件和你的权限中间件,比如:Route::resource('posts', PostController::class)->middleware(['auth', 'clearance']);在中间件内先校验用户登录状态
在ClearanceMiddleware的handle方法最开头,先判断用户是否已登录,未登录则引导到登录页或者返回未授权响应:public function handle($request, Closure $next) { // 先检查用户是否登录 if (!Auth::check()) { // 普通web应用跳转到登录页 return redirect()->route('login'); // 如果是API接口,返回JSON格式的未授权响应 // return response()->json(['message' => 'Unauthorized'], 401); } // 原有的权限检查逻辑... }检查路由配置
确认所有应用了ClearanceMiddleware的路由,都是需要用户登录才能访问的页面/接口。如果有公开路由错误绑定了这个中间件,就会触发这个错误。可选:使用空安全运算符(PHP 8+)
如果你使用的是PHP 8及以上版本,可以用空安全运算符来避免直接调用null的方法,但这只是临时规避错误,还是建议先确保用户已登录再做权限检查:if (Auth::user()?->hasPermissionTo('Administer roles & permissions'))
内容的提问来源于stack exchange,提问作者Raffi

