教你修改 Laravel "記住我" Cookie 的過期時間.

Hexor發表於2017-06-21

本文適用的 Laravel 版本: 5.2 +

問題

有時候, 網站會提供一個選項, 讓使用者在7天內免登陸, 或者30天內免登陸, 但是 Laravel 的自帶 Auth 模組沒有提供選項讓我們修改這個過期時間, 那麼我們該如何實現這個需求呢?

檢視原始碼

如果要使用 laravel 自帶的 Auth 模組是非常簡單的, 只要通過 make auth 即可安裝.

但是, 在 laravel 的預設設定中, 如果使用者勾選了 Remember Me, 那麼 Laravel 就會永久儲存這個使用者的登入狀態, 直到使用者手動 Logout.

Laravel 文件中是這樣描述的
file

在原始碼中, 也將相關的Cookie 過期時間設定為了 forever.
路徑為: vendor/laravel/framework/src/Illuminate/Auth/SessionGuard.php
file

那麼, 如何在不修改原始碼的情況下更改這一設定呢?

解決方法

在執行過 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 的過期時間了.

相關文章