在 Laravel 中,是否可以根据访问的路由动态延长会话时间?
P粉019353247
P粉019353247 2023-09-01 17:36:54
0
1
637
<p>标题几乎概括了我的问题。</p> <p>我工作的公司有一个 Laravel 应用程序,其中 <code>config/session.php</code> 上的会话时间设置为 <strong>120 分钟</strong>后过期,这是默认行为我们不想改变这个值。</p> <p>但是系统有一个特定功能,用户必须回答大量的表格/调查问卷,<strong>如果用户打字速度慢,可能需要超过 3 或 4 个小时才能完成</strong>在提交之前返回重新考虑一些答案。</p> <p>问题是,一些用户仍未完成所有问题,会话过期使他们失去进度,有时他们只有在几分钟后切换到问题的“下一页”时才发现会话过期。我们考虑过保存已经填写的数据,但即使我们用 AJAX 调用持久化内容,将已经填写的部分保存到数据库中,在回答表单时需要再次登录仍然是一个糟糕的用户体验,因为他们需要遵循无论如何,再次链接进入表单页面。由于会话过期,我们收到了很多客户的投诉。</p> <p>最好的方案是在 <code>FormController.php</code> 上创建某种函数,当用户进入表单页面或其他一些特定路由时,我们会执行类似 <code>session() 的操作->extendSessionInMinutes(360)</code>。我做了一些研究,但在 Laravel 文档(请注意我们使用的是 <code>Laravel 8.1</code>)或 Stackoverflow 上找不到类似的内容。本周阅读了有关此主题的很多内容,例如有关创建新中间件的解决方案,该中间件根据用户角色或类似内容提供不同的会话生命周期,但此选项对我们来说没有用。</p> <p>我正在开发一个解决方案,该解决方案将使用类似的解决方案在会话上添加<strong>新变量</strong> <code>session()->put('time_to_logout', now()->addHours( 2))</code> 了解会话达到 2 小时的确切时间,因此我可以<strong>将 <code>SESSION_LIFETIME</code></strong> 的默认值的生命周期增加到 5 小时,并添加JS 函数每 30 分钟检查一次,是否需要注销并将用户重定向到注销页面,如果他在表单页面上,我们将停止检查。</p> <p>但我认为这实际上不是一个好的解决方案,但我似乎无法考虑另一个解决方案。有没有办法通过以某种方式延长会话时间来完成我想要的事情?或者在不影响用户的情况下重新创建会话(<em>我敢打赌,这会弄乱表单上的 CSRF 令牌</em>),并且在他继续填写表单的同时,用 2 个小时以上的时间无缝地重新创建会话,没有注意到任何变化?</p> <p>创建会话后,无法更改其过期时间吗?是否有某种 PHP 库可以帮助我,而无需更改太多 Laravel 默认会话相关功能?</p> <p><em>提前感谢您的任何意见。</em></p>
P粉019353247
P粉019353247

全部回复(1)
P粉978551081

是的,可以。并且您需要执行以下操作-

  1. 只有通过中间件才能动态更改会话生命周期。因为通过任何控制器(没有中间件)更改它都不会更改会话值,因为会话已经启动。所以你需要一个中间件。就像下面这样-
namespace App\Http\Middleware;

class ChangeSessionValueDynamically
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, $next)
    {
        $lifetime = 1440; /* Minutes*/
        config(['session.lifetime' => $lifetime]); /* Helper function */
        return $next($request);
    }
}
  1. 之后,您需要将该中间件添加到 app/Http/Kernel.php 文件中的 $middlewarePriority 数组中,该文件必须在 Laravel 运行自己的“StartSession”中间件之前执行。就像下面这样-

\Illuminate\Session\Middleware\StartSession::class, 之前添加 \App\Http\Middleware\ChangeSessionValueDynamically::class,

/**
     * The priority-sorted list of middleware.
     *
     * This forces non-global middleware to always be in the given order.
     *
     * @var array
     */
    protected $middlewarePriority = [
     ....
     ....
        \App\Http\Middleware\ChangeSessionValueDynamically::class
        \Illuminate\Session\Middleware\StartSession::class,
     ....
     ....   
    ];
  1. 提供 \App\Http\Middleware\ChangeSessionValueDynamically::class 的别名,如下所示 -
/**
    * The application's route middleware.
    *
    * These middleware may be assigned to groups or used individually.
    *
    * @var array
    */
   protected $routeMiddleware = [
    ....
    ....
       'dynamic_session' => \App\Http\Middleware\ChangeSessionValueDynamically::class,
    ....   
    ....
   ];
  1. 将该中间件包含在路由中,如下所示 -
A) For Group Routes- 
Route::group([.., 'middleware' => ['dynamic_session', ..]], function () {
    ..
    Route::get('route_1', ['uses' => 'AbcController@index', 'as' => 'abc.index']);
    ..
}

B) OR For single Route-
Route::get('route_1', ['uses' => 'AbcController@index', 'as' => 'abc.index'])->middleware('dynamic_session');
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板