Laravel:一次只允许每个用户一个会话

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27938186/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 10:41:23  来源:igfitidea点击:

Laravel: Only allowing one session per user at a time

phpsessionlaravel

提问by David Xu

Is it possible in Laravel 4 to only allow one session per user at a time?

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

Eg, so if User logs in and already has other Sessions, those other Sessions are cancelled, preferably with a way to alert them why?

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

I'm using the Redis session driver on Amazon ElastiCache if that helps as well.

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

回答by xAoc

Yeah, I did similar for my project.

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

So, you need add to your user model another attribute in this case: last_sessid.

因此,在这种情况下,您需要向用户模型添加另一个属性: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();
}

Now, if the user has an active session, and signs in another browser, the first session will be removed.

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

P.S. Sorry for my bad english :)

PS抱歉我的英语不好:)

回答by Fershark

For laravel 5.2 after executing the make:authcommand you can create the method:public function authenticated(Request $request,User $user)in the AuthController.php and in that method you can do what you want after login. For a single session per user we add to the AuthController at top:

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

use Illuminate\Http\Request;
use Auth;

And add the function:

并添加函数:

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());
}

Remember to add the migration for altering your users table with the session_id column.

请记住使用 session_id 列添加用于更改用户表的迁移。

回答by David Xu

Managed to solve it like this:

设法解决它是这样的:

Array of SessionIds in Redis (per user)

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

example: user.sessions.[userid] [ .... ]

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

in login before filter:

在过滤器之前登录:

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()]));

This way you can also create a numeric session limit, just destroy up to NumActiveSessions - MaxSessionsin Redis.

通过这种方式,您还可以创建数字会话限制,只需NumActiveSessions - MaxSessions在 Redis 中销毁最多即可。

回答by Nazmus Shakib

This question is much earlier, but someone will be benefited through these easy steps.

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

The first step is to comment out the:

第一步是注释掉:

\Illuminate\Session\Middleware\AuthenticateSession::class,line from App\HttpKernel.phpclass.

\Illuminate\Session\Middleware\AuthenticateSession::class,App\HttpKernel.php班级线。

Secondly add this line in your login function just after login attempt successfully and before redirection: \Auth::logoutOtherDevices(request('password'));

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

That's all.

就这样。