首页 文章

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

提问于
浏览
0

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

.env 文件中,我已将 CACHE_DRIVERSESSION_DRIVER 更新为 redis .

session.phpcache.php 中,我已将 driver 设置为 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 中再次运行 SMEMBERSGET 命令证明了这一点 .

所以场景是,我试图从另一个浏览器中删除一个打开的会话,例如 FirefoxChrome . 登录 logout 链接(从 Chrome 会话 Firefox 会话)成功删除 Firefox 会话 redis-server ,但如果我尝试刷新 Firefox 浏览器,我仍然登录 .

Just an image displaying the functionality I am trying to achieve

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

谢谢

NOTE: 我已经在使用 'auth' 中间件了,所以这不是问题所在 . 另外,如果我尝试调试代码,我会在 $_COOKIE 变量和 http request 变量中看到不同的 session_ids . 这是正常的吗?

1 回答

  • 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和"remember me" 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);
        }
    }
    

相关问题