底线:
如何在会话超时时注销用户?
详细问题:
我有一个 Laravel 5.6.* 应用程序,该项目要求用户在空闲时注销。我已经尝试过这里给出的解决方案,但没有一个对我有用。
然后我偶然发现了这篇文章: https://laravel-tricks.com/tricks/session-timeout-for-logged-in-user并没有成功。
我想要的:
会话超时时自动注销用户。注销之前,将
is_logged_in
属性设置为 false
或 0
表上的 Users
。我如何实现这一目标?
到目前为止我尝试过的代码:
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,
],
];
您正在比较与中间件中相同的会话生命周期。
这意味着当会话过期时,您的中间件将不会(永远)被调用。并且用户将移至登录页面。
如果您想在数据库中保存条目,您可以设置较长的会话生存期,并在中间件中使用您自定义的注销时间。
更改 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'));
}
}
这样你的会话就不会自动过期,并且你可以操作数据。
注销前需要更新数据库。因为注销后无法执行
$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'));
}
请在中间件中检查小于120,例如下面if条件中的115或119,然后检查它
if (now()->diffInMinutes(session('lastActivityTime')) == config('session.lifetime')) {
....
}
方法一: 将元标记添加到您的 app.blade.php 文件中:
<meta http-equiv="refresh" content="{{ config('session.lifetime') * 60 }}; url=/logout">
方法2:用烤面包机
(function () {
const idleDurationSecs = 7200;
const warningDurationSecs = 5400;
let idleTimeout;
let warningTimeout;
const resetIdleTimeout = function () {
clearTimeout(warningTimeout);
warningTimeout = setTimeout(
() =>
toastr.warning(
"Please refresh the page to remain active",
"Your session is about to expire",
{ timeOut: 1800000 }
),
warningDurationSecs * 1000
);
clearTimeout(idleTimeout);
idleTimeout = setTimeout(
() => document.getElementById("logout-form").submit(),
idleDurationSecs * 1000
);
};
// Key events for reset time
resetIdleTimeout();
window.onmousemove = resetIdleTimeout;
window.onkeypress = resetIdleTimeout;
window.click = resetIdleTimeout;
window.onclick = resetIdleTimeout;
window.touchstart = resetIdleTimeout;
window.onfocus = resetIdleTimeout;
window.onchange = resetIdleTimeout;
window.onmouseover = resetIdleTimeout;
window.onmouseout = resetIdleTimeout;
window.onmousemove = resetIdleTimeout;
window.onmousedown = resetIdleTimeout;
window.onmouseup = resetIdleTimeout;
window.onkeypress = resetIdleTimeout;
window.onkeydown = resetIdleTimeout;
window.onkeyup = resetIdleTimeout;
window.onsubmit = resetIdleTimeout;
window.onreset = resetIdleTimeout;
window.onselect = resetIdleTimeout;
window.onscroll = resetIdleTimeout;
})();