// get current user
$user = Auth::user();
// logout user
$userToLogout = User::find(5);
Auth::setUser($userToLogout);
Auth::logout();
// set again current user
Auth::setUser($user);
namespace App\Http\Controllers\Admin\Auth;
use Auth;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
class LoginController extends Controller
{
use AuthenticatesUsers;
public function __construct()
{
$this->middleware('guest:admin', ['except' => 'logout']);
}
protected function guard()
{
return Auth::guard('admin');
}
public function logout()
{
// Get the session key for this user
$sessionKey = $this->guard()->getName();
// Logout current user by guard
$this->guard()->logout();
// Delete single session key (just for this user)
$request->session()->forget($sessionKey);
// After logout, redirect to login screen again
return redirect()->route('admin.login');
}
// ... Other code ...
}
public function logout(Request $request)
{
// save the teams sessions if exist
if (auth('teams')->user()) {
$teams_session_hash = 'login_teams_'.sha1('Illuminate\Auth\SessionGuard');
}
$this->guard()->logout();
$request->session()->invalidate();
$request->session()->regenerateToken();
// restores the teams sessions if exist
if (isset($teams_session_hash) && $teams_session_hash) {
$request->session()->put($teams_session_hash, auth('teams')->id());
}
return $this->loggedOut($request) ?: redirect('/');
}
7条答案
按热度按时间yquaqz181#
我不知道它是否有效,但你可以试试:
piztneat2#
我认为最快的解决方案是在用户数据库表中添加一个标志,例如一个布尔列
to_logout
,并在Auth中间件中添加类似于以下代码的内容。bakd9h0s3#
试图避免额外的复杂性,如向数据库添加字段,经过一点点调查,我遇到了下一个解决方案。
Idea基于Laravel 5.4,但应该与所有5.x版本兼容。
问题在于Laravel处理注销的方式。https://github.com/laravel/framework/blob/5.4/src/Illuminate/Foundation/Auth/AuthenticatesUsers.php#L154
$request->session()->invalidate();
行是刷新请求会话数据并重新生成ID。因此,在此之后,如果我们启用了多个防护,则它们都将被注销。我们的想法是只删除一个会话密钥,该密钥对应于我们正在注销的当前用户。如果我们检查我们的会话(注意“login_*”密钥),当来自不同守卫的用户登录时,我们将得到如下内容:
而不是刷新整个会话,我们只需要删除这个单一的,对应的键。要获得当前的守护会话名称(上面的例子中的会话键),我们可以使用guard方法:https://github.com/laravel/framework/blob/5.4/src/Illuminate/Auth/SessionGuard.php#L622
现在,我们已经具备了完成这项任务所需的一切。下面是我目前参与的项目中的示例:
使用
LoginController::logout
方法,我们用我们的自定义覆盖了trait logout(默认的Laravel logout逻辑),几乎相同,但它允许我们注销单个用户。相同的逻辑适用于我们所有的登录控制器,这取决于我们有多少不同的守卫。
我刚刚完成了这个解决方案,经过快速测试,它似乎工作正常,但请在实施前仔细检查。
xmq68pz94#
如果你使用Laravel 5.2,你可以将会话存储引擎改为数据库。在这种情况下,每个会话记录也将包含用户的ID。
所有你需要的只是从数据库中删除相应的行。
bf1o4zei5#
查看docs,似乎没有任何内置函数,类似的请求有been proposed,它也描述了跟踪在多个设备上打开多个会话的单个用户的问题。
我相信你将需要创建一个自定义的解决方案,例如(如@第纳尔所提到的)如果你在数据库中存储用户会话,那么当满足某个条件时,你可以检索并销毁特定用户的会话-更改他们的密码。
bz4sfanl6#
$findUser = User::find($userId); \Session::getHandler()->destroy($findUser->session_id);
拉腊维尔5.5
a14dhokn7#
我以前遇到过这个问题,@vkovic解释得很好,当使用guard()-〉logout()销毁每个守护会话时。我解决这个问题的方法是不同的,我仍然使用默认的注销过程,但我恢复了我想要保留的守护会话。