【问题标题】:Laravel: Only allowing one session per user at a timeLaravel:每个用户一次只允许一个会话
【发布时间】:2015-03-12 08:32:36
【问题描述】:

在 Laravel 4 中是否可以一次只允许每个用户一个会话?

例如,如果用户登录并且已经有其他会话,那么那些其他会话将被取消,最好是通过某种方式提醒他们为什么?

如果有帮助的话,我正在 Amazon ElastiCache 上使用 Redis 会话驱动程序。

【问题讨论】:

  • 一次只能激活一个会话,只能将不同的数据同时进行多个“会话”。
  • 什么意思?在 Laravel 4 中,默认情况下,一个用户可以在不同的机器上使用同一个帐户多次登录,并且所有这些会话都将有效。我想这样做,一旦他们登录,附加到他们的 UserId 的所有其他会话都将被取消。
  • 好的,我现在明白了,但要解决这个问题,您需要查询会话驱动程序以获取连接到给定用户的所有会话并删除它们。通常我会把它放在一个数据库中,然后删除其他的,但在你的情况下,我不知道解决方案。

标签: php session laravel


【解决方案1】:

是的,我为我的项目做了类似的事情。

因此,在这种情况下,您需要向用户模型添加另一个属性:last_sessid。

public function swapping($user) {
    $new_sessid   = \Session::getId(); //get new session_id after user sign in
    $last_session = \Session::getHandler()->read($user->last_sessid); // retrive last session

    if ($last_session) {
        if (\Session::getHandler()->destroy($user->last_sessid)) {
            // session was destroyed
        }
    }

    $user->last_sessid = $new_sessid;
    $user->save();
}

现在,如果用户有一个活动会话,并在另一个浏览器中登录,第一个会话将被删除。

附:对不起我的英语不好:)

【讨论】:

  • 不就是会话再生吗?如果他在GMail中遇到问题,您可以在5台机器上登录而他想在其他4台机器上注销用户?我认为你的代码并没有解决他的问题。
  • 例如:您登录 chrome,然后打开 firefox 并登录,然后,当您返回 chrome 并尝试仅对登录用户执行需要权限的操作时,您的身份验证过滤器将抛出异常, 或重定向错误等...对我来说,这段代码完美地工作 1 个用户 - 1 个会话
  • 但它禁止用户同时在多个地方登录,然后只能选择从所有其他地方注销。
  • 如果我理解正确的话,是的,你不能选择删除哪个会话,但是如果你想选择,你应该保存用户的所有 session_id...
  • 我怎样才能做到这一点,但只有 2 次会话并且不允许登录到第 3 次会话。
【解决方案2】:

对于 laravel 5.2,在执行 make:auth 命令后,您可以在 AuthController.php 中创建方法:public function authenticated(Request $request,User $user),在该方法中您可以在登录后做您想做的事情。 对于每个用户的单个会话,我们添加到顶部的 AuthController:

use Illuminate\Http\Request;
use Auth;

并添加功能:

public function authenticated(Request $request,User $user){
    $previous_session = $user->session_id;

    if ($previous_session) {
        \Session::getHandler()->destroy($previous_session);
    }

    Auth::user()->session_id = \Session::getId();
    Auth::user()->save();
    return redirect()->intended($this->redirectPath());
}

记得添加迁移以使用 session_id 列更改用户表。

【讨论】:

    【解决方案3】:

    设法像这样解决它:

    Redis 中的 SessionId 数组(每个用户)

    示例:user.sessions.[userid] [ .... ]

    在过滤前登录:

    foreach (json_decode($redis->get('user.sessions.$userId')) as $sesId) {
       Session::getHandler()->destroy($sesId));
    }
    
    // add session to redis
    $redis->set('user.sessions.$userId', json_encode([Session::getId()]));
    

    这样你还可以创建一个数字会话限制,只需在 Redis 中销毁 NumActiveSessions - MaxSessions

    【讨论】:

      【解决方案4】:

      这个问题要早得多,但有人会通过这些简单的步骤受益。

      第一步是注释掉:

      \Illuminate\Session\Middleware\AuthenticateSession::class, 来自App\HttpKernel.php 类的行。

      在登录尝试成功之后和重定向之前,在您的登录函数中再次添加此行: \Auth::logoutOtherDevices(request('password'));

      就是这样。

      【讨论】:

        猜你喜欢
        • 2012-06-02
        • 2019-10-19
        • 1970-01-01
        • 2014-10-11
        • 2015-11-03
        • 1970-01-01
        • 2014-02-11
        • 2013-11-10
        • 1970-01-01
        相关资源
        最近更新 更多