Login bawaan kita hanya bertahan selama session hidup — 120 menit sejak aktivitas terakhir, sesuai konfigurasi SESSION_LIFETIME. Bagi aplikasi yang dibuka berkali-kali sepanjang hari, diminta login ulang setiap dua jam terasa melelahkan. Fitur remember me menyelesaikannya: satu centang di formulir login, dan login bertahan berbulan-bulan lamanya melewati batas session. Kuncinya bukan memperpanjang umur session, melainkan cookie terpisah bernama recaller yang bisa membangkitkan login baru kapan pun session sudah mati.
Mengaktifkan remember pada Auth::attempt() #
Argumen kedua Auth::attempt() adalah saklar yang kita cari. Formulir login mengirim checkbox remember, lalu controller meneruskannya sebagai boolean:
public function login(Request $request)
{
$credentials = $request->validate([
'email' => ['required', 'email'],
'password' => ['required'],
]);
$remember = $request->boolean('remember');
if (Auth::attempt($credentials, $remember)) {
$request->session()->regenerate();
return redirect()->intended('/dashboard');
}
return back()->withErrors([
'email' => 'Email atau password salah.',
])->onlyInput('email');
}$request->boolean('remember') mengubah nilai checkbox ("1", "0", atau tidak ada) menjadi boolean yang aman dipakai. Saat true, guard web melakukan dua hal ekstra: mengisi kolom remember_token milik user dengan string acak 60 karakter bila masih kosong, lalu mengirim cookie recaller ke browser.
Kolom remember_token sendiri sudah tersedia sejak migrasi bawaan lewat $table->rememberToken() — varchar nullable sepanjang 100 karakter di tabel users.
Cara Kerja Cookie remember_web #
Cookie recaller diberi nama remember_web_ diikuti hash guard — pada aplikasi kita namanya persis:
remember_web_59ba36addc2b2f9401580f014c7f58ea4e30989dIsinya tiga bagian yang dipisah tanda pipe: ID user, remember token, dan HMAC dari hash password:
{id_user}|{remember_token}|{hmac_password_hash}Perbandingan keduanya — session login versus remember me — bisa dirangkum begini:
| Aspek | Login session biasa | Remember me |
|---|---|---|
| Penyimpan sisi server | baris data session | kolom users.remember_token |
| Penyimpan sisi browser | cookie session | cookie remember_web_* |
| Umur bawaan | 120 menit (SESSION_LIFETIME) | 576.000 menit (400 hari) |
| Selamat dari session expiry | tidak | ya |
Alur pemulihannya bekerja seperti ini. Saat request datang tanpa session yang sah (misalnya session sudah kedaluwarsa atau dihapus), SessionGuard::user() tidak menemukan ID login di session, lalu memeriksa cookie recaller. Guard mencari user berdasarkan ID di cookie, mencocokkan token cookie dengan kolom remember_token memakai hash_equals(), memverifikasi bagian HMAC terhadap hash password saat ini, dan baru menuliskan login ke session yang baru. Karena verifikasi melibatkan hash password, mengganti password otomatis mematikan semua recaller lama.
Logout Membuang remember token #
Auth::logout() tidak berhenti pada membersihkan session. Guard juga menghapus cookie recaller dari sisi browser dan, bila user memiliki remember token, menggantinya dengan token acak baru. Recaller lama yang mungkin masih tersimpan di browser mana pun menjadi tidak berlaku karena token di database sudah bukan token itu lagi — mekanisme ini disebut token cycling.
Kapan sebaiknya kita menawarkan remember me? Pada perangkat pribadi yang rutin dipakai: ya. Pada komputer bersama di warnet atau kantor publik: jangan — centang itu sama saja menitipkan akses akun ke siapa pun yang memakai komputer berikutnya.
Menguji Skenario Session Expired #
Skenario paling menarik untuk diuji adalah: cookie session hangus, tetapi cookie remember masih ada. Feature test mensimulasikannya dengan $this->refreshApplication() — aplikasi di-boot ulang sehingga session store benar-benar baru, meniru browser yang datang tanpa cookie session — lalu kita hanya mengirim ulang cookie recaller:
public function test_remember_cookie_menghidupkan_sesi_setelah_session_expired(): void
{
$user = User::factory()->create([
'name' => 'Budi',
'email' => '[email protected]',
'password' => 'rahasia-budi-123',
]);
// Perangkat 1: login dengan remember
$login = $this->post('/login', [
'email' => '[email protected]',
'password' => 'rahasia-budi-123',
'remember' => '1',
]);
$recallerCookie = collect($login->headers->getCookies())
->first(fn ($cookie) => str_starts_with($cookie->getName(), 'remember_'));
// Simulasi session cookie hangus
$this->refreshApplication();
// Hanya kirim ulang cookie remember
$this->withUnencryptedCookie(
$recallerCookie->getName(),
$recallerCookie->getValue()
);
$this->get('/dashboard')->assertOk();
}Output yang Dihasilkan:
login_remember: cookie=remember_web_59ba36addc2b2f9401580f014c7f58ea4e30989d, token_db_panjang=60
sesi_baru_tanpa_session_cookie: status=200, login_pulih=ya, via_remember=ya
logout: token_diganti=ya
cookie_lama_setelah_logout: status=302, target=http://localhost:8000/login
login_tanpa_remember: cookie_remember=tidak ada, token_db=tetap-nullEmpat baris pertama membuktikan pemulihan login dari cookie semata — via_remember=ya menegaskan guard mengenalinya lewat jalur recaller. Dua baris berikutnya membuktikan logout benar-benar mematikan cookie lama, dan baris terakhir menunjukkan login tanpa centang remember tidak mengirim cookie apa pun.
Login jangka panjang teratasi, tetapi bagaimana dengan pengguna yang login di banyak perangkat sekaligus dan ingin mengelolanya? Session management adalah chapter berikutnya. Detail lengkap fitur ini bisa dipelajari di dokumentasi Authentication bagian Remembering Users.