Laravel – AuthenticateSession 在多Guard下工作不正常
在laravel中,一个账号可以多地方同时登录,有时候会存在一个问题,就是比如你修改密码后,这些都登录的人不会立即退出登录,还是登录状态。
如何让其他设备上的 Session 失效?
laravel为我们提供了方法,只是默认他是注释掉了。

Laravel 提供了让用户 Session 在除当前设备之外的其他登录设备上失效的机制,要实现这个功能,要将 Illuminate\Session\Middleware\AuthenticateSession 中间件在 app/Http/Kernel.php 类的 web 中间件组中的注释取消:

取消注释后,如果修改了用户密码,则此账号所有session都会失效。
当然,你也可以使用 Auth
门面上的 logoutOtherDevices
方法实现在其他设备「退出」,该方法要求用户提供登录密码:
use Illuminate\Support\Facades\Auth; Auth::logoutOtherDevices($password);
但是如果你存在多个guard,不会发现, AuthenticateSession 会存在问题,不同的guard 在同一浏览器下登录,会互相挤掉。
查看 Illuminate\Session\Middleware\AuthenticateSession 的代码,你会发现,代码中没有区分guard,只用了一个session key “password_hash”。
因此,不同gurad 用户的password_hash不同,就会退出登录。

要解决这个问题,就需要自己重新 AuthenticateSession 部分代码。
1、在app\Http\Middleware目录下新建AuthenticateSession.php
2、类名 AuthenticateSession 继承 Illuminate\Session\Middleware\AuthenticateSession
<?php namespace App\Http\Middleware; use Closure; use Illuminate\Auth\AuthenticationException; class AuthenticateSession extends \Illuminate\Session\Middleware\AuthenticateSession { public function getPasswordName() { $name = $this->auth->getName(); return str_replace('login_', 'password_hash_', $name); } public function handle($request, Closure $next) { if (!$request->user() || !$request->session()) { return $next($request); } if ($this->auth->viaRemember()) { $passwordHash = explode('|', $request->cookies->get($this->auth->getRecallerName()))[2]; if ($passwordHash != $request->user()->getAuthPassword()) { $this->logout($request); } } if (!$request->session()->has($this->getPasswordName())) { $this->storePasswordHashInSession($request); } if ($request->session()->get($this->getPasswordName()) !== $request->user()->getAuthPassword()) { $this->logout($request); } return tap($next($request), function () use ($request) { $this->storePasswordHashInSession($request); }); } protected function logout($request) { $this->auth->logout(); $request->session()->forget($this->auth->getName()); $request->session()->forget($this->getPasswordName()); throw new AuthenticationException; } }
3、修改 app/Http/Kernel.php 类的 web 中间件组 ,添加我们自定义的中间件。

好了,现在多gurad下使用就没问题了。