在 Laravel 中,是否可以根據存取的路由動態延長會話時間?
P粉019353247
P粉019353247 2023-09-01 17:36:54
0
1
556
<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');
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!