2016-04-21 147 views
2

在我的laravel 5应用程序中,有一项功能允许具有管理员角色的用户重置任何人的密码,而不是管理员,但这不会强制该人员注销并再次登录。如何强制用户在密码更改后退出?我没有对中间件进行任何更改来验证用户或任何东西。Laravel 5注销特定用户

回答

2

我认为最快的解决方案是为用户数据库表添加一个标志,例如布尔列to_logout,并在Auth中间件中添加类似此代码的内容。

$user = Auth::user(); 

if($user->to_logout){ 
    Auth::logout(); 
    $user->update(['to_update' => 0]); 

    return redirect('/'); 
} 
+0

感谢克劳迪奥,这正是我所考虑的。我只是确保我正在为Laravel做正确的方式。 – Goderaftw

+1

我不认为这种方法会破坏用户的所有会话(例如,如果他同时登录了电脑和手机) –

1

如果您使用Laravel 5.2,则可以将会话存储引擎更改为数据库。在这种情况下,每个会话记录还将包含用户的ID。

所有你需要的只是从数据库中删除相应的行。

+0

但是,该项目是在Laravel 5.0中构建的。我已经考虑过在数据库中设置一个字段的选项,例如'password_changed'并检查中间件中的字段,这是否可行? – Goderaftw

+0

当然。好的解决方案 – Dinar

0

查看docs,它没有出现任何内置函数,类似的请求也有been proposed,它也描述跟踪单个用户在多个设备上打开多个会话的问题。

我相信你需要创建一个自定义的解决方案,例如(如@Dinar提到的),如果你将用户会话存储在数据库中,那么当满足某些条件时你可以检索和销毁特定用户的会话 - 他们的密码。

6

我不知道这是否会工作,但你可以尝试:

// get current user 
$user = Auth::user(); 

// logout user 
$userToLogout = User::find(5); 
Auth::setUser($userToLogout); 
Auth::logout(); 

// set again current user 
Auth::setUser($user); 
+0

这就是我一直在寻找的!谢谢! – BakerStreetSystems

0

试图避免像添加字段,数据库,调查后的点点我遇到下一个解决方案来了额外的复杂性。

想法基于Laravel 5.4,但应与所有5.x版本兼容。

问题在于Laravel处理注销的方式。正如我们在https://github.com/laravel/framework/blob/5.4/src/Illuminate/Foundation/Auth/AuthenticatesUsers.php#L154

public function logout(Request $request) 
{ 
    $this->guard()->logout(); 

    $request->session()->invalidate(); 

    return redirect('/'); 
} 

线看$request->session()->invalidate();被刷新请求会话数据,并重新生成ID。所以在这之后,如果我们启用了多个警卫,他们都会被注销。

这个想法是删除一个会话密钥,它对应于我们正在注销的当前用户。如果我们考察我们的会话(注意“login_ *”键),而来自不同卫士用户登录,我们会得到这样的事情:

array:5 [▼ 
    "_token" => "qB4zDqDbknpO7FOrfNQ3YuFxpnji95uamJflxSkV" 
    "_previous" => array:1 [▶] 
    "_flash" => array:2 [▶] 
    "login_admin_51ba36addc2b2f9401580f014c7f58ea4e30989d" => 74 
    "login_user_51ba36addc2b2f9401580f014c7f58ea4e30989d" => 23 
] 

相反冲洗整个会话的,我们只需要删除这个单一的相应的键。要获得当前的保护会话名称(上例中的会话密钥),我们可以使用保护方法: https://github.com/laravel/framework/blob/5.4/src/Illuminate/Auth/SessionGuard.php#L622

现在我们拥有了执行此任务所需的一切。下面是该项目的例子,我目前:

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 ... 

} 

随着LoginController::logout方法我们覆盖特质注销(默认Laravel注销逻辑)与我们的习惯,几乎是相同的,但它将使我们能够注销单个用户。

同样的逻辑适用于我们所有的登录控制器,具体取决于我们拥有多少不同的警卫。

我刚完成这个解决方案,经过快速测试,它似乎工作正常,但请在实施前仔细检查它。