Laravel 5.5全局中间件中Auth::user()返回null问题求助
兄弟,你这个问题我太熟了!核心问题出在全局中间件的执行顺序上——你把FirstLoginPasswordChange放在全局中间件列表的最后,但负责处理用户认证的那些中间件(不管是Laravel自带的会话/认证中间件,还是Zizaco Entrust相关的),在全局中间件阶段根本还没执行,所以此时调用Auth::user()自然拿不到用户信息,返回null是完全正常的。
先看你贴的代码:
你的app/Http/Kernel.php代码
class Kernel extends HttpKernel { /** * The application's global HTTP middleware stack. * * These middleware are run during every request to your application. * * @var array */ protected $middleware = [ \Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class, \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class, \App\Http\Middleware\TrimStrings::class, \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class, \App\Http\Middleware\TrustProxies::class, \App\Http\Middleware\FirstLoginPasswordChange::class, ]; }
你的FirstLoginPasswordChange中间件代码
use Illuminate\Support\Facades\Auth; use Zizaco\Entrust\Entrust; public function handle($request, Closure $next) { dd(Auth::user()); // returns null // or dd(Auth::check()); // returns false // or dd(\Entrust::user()); // returns null return $next($request); }
给你几个可行的解决方法
1. 把自定义中间件移到web中间件组(最推荐)
Laravel的web中间件组已经内置了处理会话、认证的核心中间件(比如StartSession、AuthenticateSession),这些会在你的自定义中间件之前执行,这样就能顺利拿到用户信息了。修改Kernel.php里的$middlewareGroups部分:
protected $middlewareGroups = [ 'web' => [ \App\Http\Middleware\EncryptCookies::class, \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, \Illuminate\Session\Middleware\StartSession::class, // \Illuminate\Session\Middleware\AuthenticateSession::class, \Illuminate\View\Middleware\ShareErrorsFromSession::class, \App\Http\Middleware\VerifyCsrfToken::class, \Illuminate\Routing\Middleware\SubstituteBindings::class, // 把你的中间件加到web组的最后 \App\Http\Middleware\FirstLoginPasswordChange::class, ], 'api' => [ 'throttle:60,1', 'bindings', ], ];
记得同时把FirstLoginPasswordChange从全局的$middleware数组里删掉,避免重复执行。
2. 调整全局中间件顺序(不推荐)
如果你非要把这个中间件放在全局中间件里,那必须确保它在所有认证相关的中间件之后执行。你需要手动把StartSession、AuthenticateSession这些会话/认证中间件加到全局$middleware列表里,并且放在你的自定义中间件前面。不过这种做法会让所有请求(包括不需要会话的API请求)都跑会话逻辑,非常不灵活,所以不建议这么做。
3. 针对Entrust的额外检查
因为你用了Zizaco Entrust,还要确认一下Entrust的中间件是否已经正确注册。Entrust的EntrustMiddleware需要在Laravel的认证中间件之后执行,所以如果是放在web组里,要确保它在你的FirstLoginPasswordChange中间件之前,这样\Entrust::user()才能拿到正确的用户数据。
内容的提问来源于stack exchange,提问作者Ilya Kolesnikov

