【问题标题】:Laravel 5 Logout Specific UserLaravel 5 注销特定用户
【发布时间】:2016-08-14 22:17:53
【问题描述】:

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

【问题讨论】:

    标签: php laravel laravel-5


    【解决方案1】:

    $findUser = User::find($userId); \Session::getHandler()->destroy($findUser->session_id);

    Laravel 5.5

    【讨论】:

    • 欢迎来到 Stack Overflow。虽然您的代码可能会提供问题的答案,但请在其周围添加上下文,以便其他人了解它的作用以及它存在的原因。
    【解决方案2】:

    为了避免额外的复杂性,比如向 db 添加字段,经过一点调查后,我遇到了下一个解决方案。

    Idea 基于 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 注销逻辑),几乎相同,但允许我们注销单个用户。

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

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

    【讨论】:

      【解决方案3】:

      我不知道它是否会起作用,但你可以尝试:

      // get current user
      $user = Auth::user();
      
      // logout user
      $userToLogout = User::find(5);
      Auth::setUser($userToLogout);
      Auth::logout();
      
      // set again current user
      Auth::setUser($user);
      

      【讨论】:

      • 这就是我要找的!谢谢!
      • 它对我不起作用。我的会话驱动程序是文件。是这样吗?
      【解决方案4】:

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

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

      【讨论】:

      • 感谢克劳迪奥,这正是我正在考虑做的事情。我只是确保我以正确的方式为 Laravel 做这件事。
      • 我认为这种方法不会破坏用户的所有会话(例如,如果他同时登录电脑和手机)
      • 实际上这只会使当前登录用户的会话无效。
      【解决方案5】:

      查看docs,似乎没有任何内置功能,类似的请求有been proposed,它还描述了跟踪在多个会话上打开多个会话的单个用户的问题设备。

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

      【讨论】:

        【解决方案6】:

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

        您只需要从数据库中删除相应的行。

        【讨论】:

        • 这个项目是在 Laravel 5.0 中构建的。我已经考虑过在数据库中设置一个字段(例如“password_changed”)并在中间件中检查它,这是一个可行的选择吗?
        • 当然。很好的解决方案。
        猜你喜欢
        • 2014-08-08
        • 2016-08-22
        • 1970-01-01
        • 2016-02-13
        • 2017-05-17
        • 2016-11-04
        • 2019-11-13
        • 2015-09-30
        • 2016-03-21
        相关资源
        最近更新 更多