我正在跟踪我网站中用户的登录历史记录,为此我需要显示是否在其他浏览器或设备中打开了任何其他会话。另外,我需要提供一种功能,其中用户可以注销在当前会话中在不同浏览器/设备中打开的会话。我正在使用 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 。这是正常的吗?
答案 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);
}
}