从另一个浏览器注销一个浏览器会话 - LARAVEL 5.2

时间:2016-06-03 13:26:18

标签: php laravel session redis laravel-5.2

我正在跟踪我网站中用户的登录历史记录,为此我需要显示是否在其他浏览器或设备中打开了任何其他会话。另外,我需要提供一种功能,其中用户可以注销在当前会话中在不同浏览器/设备中打开的会话。我正在使用 redis-server 。到目前为止,我所做的事情如下:

.env 文件中,我已将 CACHE_DRIVER SESSION_DRIVER 更新为 redis的 即可。

session.php cache.php 中,我已将驱动程序设置为 redis < /强>

接下来,在登录时,我连接到 redis 服务器并存储特定用户的会话ID。

 $redis = Redis::connection();
 $redis->sadd('user:sessions:'. Auth::user()->id, $session_id); 

完成此操作后,我可以使用 redis-cli 命令查看每个用户的多个会话ID。

> SMEMBERS user:sessions:1
> "95008658737a7f937c614bccbb748443a649c515"
> "f1f14db9b1760254a4072fe9b440f9acbacc8974"
> GET laravel:95008658737a7f937c614bccbb748443a649c515 
> "s:332:\"a:5:{s:6:\"_token\";s:40:\"HAuA200irzF63fgFw4vCVkrsZNuqTk6o2XLkHzlu\";s:9:\"_previous\";a:1:{s:3:\"url\";s:33:\"http://localhost:8000/security\";}s:5:\"flash\";a:2:{s:3:\"old\";a:0:{}s:3:\"new\";a:0:{}}s:50:\"login_web_59ba36addc2b2f9401580f014c7f58ea4e30989d\";i:1;s:9:\"_sf2_meta\";a:3:{s:1:\"u\";i:1464957596;s:1:\"c\";i:1464957416;s:1:\"l\";s:1:\"0\";}}\";"

此输出让我假设用于在laravel中存储会话的 redis 选项工作正常。

接下来,为了从特定会话中注销用户,我使用以下一组说明:

public function logoutSession($session_id) {
     $redis = Redis::connection();
     $redis->del('laravel:' . $session_id);
     $redis->srem('user:sessions:' . Auth::user()->id, $session_id);
} 

调用此函数后,相应的会话ID将被成功删除。

redis-cli 中再次运行 SMEMBERS GET 命令证明了这一点。

所以情况是,我尝试删除一个会话,比如说, Firefox 来自另一个浏览器, Chrome 。点击 退出 链接( Firefox 会话 Chrome < / strong> session)成功删除 redis-server 中的 Firefox 会话,但是如果我尝试刷新 Firefox 浏览器,我仍然登录。

Just an image displaying the functionality I am trying to achieve

我无法理解我到底错在哪里。任何形式的帮助都将受到高度赞赏。

由于

注意:我已经在使用&#39; auth&#39; 中间件,因此这不是问题所在。另外,如果我尝试调试代码,我会在 $ _ COOKIE 变量和 http请求变量中看到不同的 session_ids 。这是正常的吗?

1 个答案:

答案 0 :(得分:0)

我自己也遇到过类似的问题。我对缓存失效等感到沮丧......然后再次经过“登录”过程后,我忘记检查“记住我”的cookie。

https://laravel.com/docs/master/authentication#remembering-users

原来我已成功清除了缓存,但需要调用:

Auth::logout();

为了从数据库中删除“remember_token”。否则,Laravel认为这是重新启动Auth系统,重新登录用户并设置新会话cookie的有效方法。

使用您的代码:

public function logoutSession($session_id) {
    $redis = Redis::connection();
    $redis->del('laravel:' . $session_id);
    $redis->srem('user:sessions:' . Auth::user()->id, $session_id);
    Auth::logout();
}

但是这会从所有会话中退出,包括您正在使用的会话。

对于您的问题,我建议使用Auth::viaRemember()方法来确定创建请求的客户端是否与您当前正在使用的cookie一起创建请求。它区分您当前的会话cookie和“记住我”cookie:

if (Auth::viaRemember())
{
    // Check Redis for session info
    // Do something if not found, otherwise just proceed
}

**EDIT**:我在发布答案后发现了这一点:Laravel Auth::logout not removing remember me cookie

所以回顾一下:

if (Auth::viaRemember())
{
    if (!Redis::get($key))
    {
        // Get remember_me cookie name
        $rememberMeCookie = Auth::getRecallerName();

        // Tell Laravel to forget this cookie
        $cookie = Cookie::forget($rememberMeCookie);

        return Redirect::to('/')->withCookie($cookie);
    }
}