Laravel 会话超时,额外的注销代码
Posted
技术标签:
【中文标题】Laravel 会话超时,额外的注销代码【英文标题】:Laravel session timeout, extra logout code 【发布时间】:2020-03-20 17:10:47 【问题描述】:底线:
如何在会话超时时注销用户?
详细问题:
我有一个 Laravel 5.6.* 应用程序,该项目要求用户在用户空闲时注销。我已经尝试过这里给出的解决方案,但没有一个对我有用。
然后我偶然发现了这篇文章: https://laravel-tricks.com/tricks/session-timeout-for-logged-in-user 并没有成功。
我想要什么:
在会话超时时自动注销用户。在注销之前,将Users
表上的is_logged_in
属性设置为false
或0
。我如何做到这一点?
到目前为止我尝试过的代码:
session.php
/*
|--------------------------------------------------------------------------
| Session Lifetime
|--------------------------------------------------------------------------
|
| Here you may specify the number of minutes that you wish the session
| to be allowed to remain idle before it expires. If you want them
| to immediately expire on the browser closing, set that option.
|
*/
'lifetime' => env('SESSION_LIFETIME', 120),
'expire_on_close' => false,
SessionTimeOut.php
中间件
<?php
namespace App\Http\Middleware;
use Closure;
use App\Traits\CacheQueryResults;
class SessionTimeOut
use CacheQueryResults;
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
// session()->forget('lastActivityTime');
if (! session()->has('lastActivityTime'))
session(['lastActivityTime' => now()]);
// dd(
// session('lastActivityTime')->format('Y-M-jS h:i:s A'),
// now()->diffInMinutes(session('lastActivityTime')),
// now()->diffInMinutes(session('lastActivityTime')) >= config('session.lifetime')
// );
if (now()->diffInMinutes(session('lastActivityTime')) >= (config('session.lifetime') - 1) )
if (auth()->check() && auth()->id() > 1)
$user = auth()->user();
auth()->logout();
$user->update(['is_logged_in' => false]);
$this->reCacheAllUsersData();
session()->forget('lastActivityTime');
return redirect(route('users.login'));
session(['lastActivityTime' => now()]);
return $next($request);
Kernel.php
/**
* The application's route middleware groups.
*
* @var array
*/
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
// \Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\App\Http\Middleware\SessionTimeOut::class,
],
];
【问题讨论】:
会话超时后屏幕上是否显示任何错误? 不。没有错误,它只是注销但不对数据库执行任何数据库操作。 在注销前执行数据库操作或尝试使用像 \Auth::guard('admin')->logout();return redirect()->route('admin.login'); 不。还是一样。 您是否获得了更新的用户详细信息 dd($user);更新后?is_logged_in=false in db? 【参考方案1】:您正在比较与中间件中相同的会话生命周期。
这意味着当会话到期时,您的中间件将不会(永远)被调用。用户将移动到登录页面。
如果您想在数据库中保存条目,您可以设置长时间会话生存期,并在中间件中使用您自定义的时间来注销。
config/session.php 中的变化
'lifetime' => 525600, // for one year, it will be in minute, use as you want.
中间件更改如下,两小时后退出。
if (now()->diffInMinutes(session('lastActivityTime')) >= (120) ) // also you can this value in your config file and use here
if (auth()->check() && auth()->id() > 1)
$user = auth()->user();
auth()->logout();
$user->update(['is_logged_in' => false]);
$this->reCacheAllUsersData();
session()->forget('lastActivityTime');
return redirect(route('users.login'));
通过这种方式,您的会话不会自动过期,您可以操作数据。
【讨论】:
您的解决方案有效,但前提是session('lastActivityTime')
有价值。当会话过期时,session('lastActivity')
会被 Laravel 自动更新并重定向到登录页面。在此之前,我想将is_logged_in
属性设置为false
或0
,我该如何实现?
这就是我想说的。如果会话自动过期,我们无法获取数据,因此解决方案是增加会话生命周期,在中间件中,使用自定义时间注销。检查更新的答案。【参考方案2】:
注销前需要更新数据库。因为注销后无法执行$user->update()
。所以请尝试以下方式:
if (auth()->check() && auth()->id() > 1)
$user = auth()->user();
$user->update(['is_logged_in' => false]);
$this->reCacheAllUsersData();
session()->forget('lastActivityTime');
//Add Logout method here..
auth()->logout();
return redirect(route('users.login'));
【讨论】:
不。它没有用。仅在应用您的解决方案后,is_logged_in
列才设置为 1
。
@SaiyanPrince 这意味着数据库已更新。现在的问题是你想在is_logged_in
列中保存什么?是true or false
还是0 or 1
。
不。 1
即true
在用户登录时设置。我想在用户通过会话超时注销时将其设置为false
或0
。我已经完成了手动过程。我现在正在寻找数据库表的自动更新。【参考方案3】:
请在中间件中检查小于120,例如如果条件低于115或119,然后检查它
if (now()->diffInMinutes(session('lastActivityTime')) == config('session.lifetime'))
....
【讨论】:
以上是关于Laravel 会话超时,额外的注销代码的主要内容,如果未能解决你的问题,请参考以下文章