本文適用的 Laravel 版本: 5.2 +
問題
有時候, 網站會提供一個選項, 讓使用者在7天內免登陸, 或者30天內免登陸, 但是 Laravel 的自帶 Auth 模組沒有提供選項讓我們修改這個過期時間, 那麼我們該如何實現這個需求呢?
檢視原始碼
如果要使用 laravel 自帶的 Auth 模組是非常簡單的, 只要通過 make auth
即可安裝.
但是, 在 laravel 的預設設定中, 如果使用者勾選了 Remember Me, 那麼 Laravel 就會永久儲存這個使用者的登入狀態, 直到使用者手動 Logout.
Laravel 文件中是這樣描述的
在原始碼中, 也將相關的Cookie 過期時間設定為了 forever.
路徑為: vendor/laravel/framework/src/Illuminate/Auth/SessionGuard.php
那麼, 如何在不修改原始碼的情況下更改這一設定呢?
解決方法
在執行過 make auth
之後, 在 Controllers 資料夾中, 系統會幫我建立一個 Auth 資料夾, 這個資料夾裡放置了一些登入用的 Controller, 我們只要對其中的 LoginController 做一些修改, 就可以實現我們的需求了.
基本思路是這樣的, 在 Laravel 將 remember_token 的過期時間設定為 forever 之後, 這個時候還沒有將 Cookie 發回到瀏覽器, 所以我們只要在發回瀏覽器之前, 再次修改這個 Cookie 的有效期即可.
在開啟 LoginController 之後, 我們可以看到
use AuthenticatesUsers;
也就是說 LoginController
使用了 AuthenticatesUsers
trait 中的方法, 我們進入 AuthenticatesUsers
這個 trait. 很容易找到 sendLoginResponse
這個方法, 這個方法的作用是在成功驗證使用者資訊後, 返回登入成功的訊息給瀏覽器. 所以我們只要重寫這個方法, 並且在這個方法里加入對 Cookie 有效期的修改操作即可實現我們的需求.
接下來, 我們就在 LoginController 中重寫一次這個方法.
首先我們直接將 protected function sendLoginResponse(Request $request)
這個方法從 AuthenticatesUsers
複製到 LoginController
中, 然後再加入修改 Cookie 的程式碼即可. 修改後的 LoginController
會像下面這樣
class LoginController extends Controller
{
...
protected function sendLoginResponse(Request $request)
{
// 設定記住我的時間為60分鐘
$rememberTokenExpireMinutes = 60;
// 首先獲取 記住我 這個 Cookie 的名字, 這個名字一般是隨機生成的,
// 類似 remember_web_59ba36addc2b2f9401580f014c7f58ea4e30989d
$rememberTokenName = Auth::getRecallerName();
// 再次設定一次這個 Cookie 的過期時間
Cookie::queue($rememberTokenName, Cookie::get($rememberTokenName), $rememberTokenExpireMinutes);
// 下面的程式碼是從 AuthenticatesUsers 中的 sendLoginResponse() 直接複製而來
$request->session()->regenerate();
$this->clearLoginAttempts($request);
return $this->authenticated($request, $this->guard()->user())
?: redirect()->intended($this->redirectPath());
}
}
結束
好了, 現在你就可以在沒有修改原始碼的情況下, 自定義 "記住我" Cookie 的過期時間了.