Laravel 会话超时,额外的注销代码

Laravel session timeout, extra logout code

底线:

如何在会话超时时注销用户?


详细问题:

我有一个 Laravel 5.6.* 应用程序,该项目要求用户在空闲时注销。我已经尝试过此处提供的解决方案,但其中 none 对我有用。

然后我偶然发现了这个 post: https://laravel-tricks.com/tricks/session-timeout-for-logged-in-user 并没有成功。


我想要的:

在会话超时时自动注销用户。注销前,在 Users table 上将 is_logged_in 属性设置为 false0。我该如何实现?


目前我试过的代码:

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,
     ],
];

注销前需要更新数据库。因为注销后无法执行$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')) {
....
}

您正在比较与中间件相同的会话生命周期。

这意味着当会话过期时,您的中间件将不会(永远)called.And 用户将移动到登录页面。

如果你想在数据库中保存条目,你可以设置长时间的会话生存期,并在中间件中使用你自定义的时间来注销。

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'));
       }

   }

通过这种方式,您的会话不会自动过期,您可以操作数据。