In Laravel, how does remember me work with Auth::attempt, the remember_token column and the recaller cookie, and what does Auth::viaRemember() report?
answer
- second argument to attempt()
- remember_token: string(100), nullable
- cookie holds id|token|password-hash HMAC
- 576000 minutes unless the guard sets remember
- viaRemember: restored from the cookie this request
basics
~20 sPassing true as attempt()'s second argument stores a random remember_token and queues a long-lived encrypted cookie with the user ID, that token and a password-hash HMAC. When the session is gone the guard restores the user from it, and Auth::viaRemember() returns true.
solid answer
~40 s`Auth::attempt($credentials, $request->boolean('remember'))` (or `login($user, true)`) makes the session guard set a 60-character `remember_token` on the user if it is empty, stored in the `remember_token` column that `$table->rememberToken()` creates as a nullable 100-character string. It then queues a cookie named `remember_web_<hash>` whose value is `id|remember_token|HMAC-SHA256(password hash, APP_KEY)`, encrypted by the `EncryptCookies` middleware, lasting 576,000 minutes (400 days) unless the guard's config sets `remember` in minutes. Later, when the session has no user ID, the guard reads that cookie, loads the user by ID and token, checks the HMAC against the current password hash, and signs them in with a fresh session; `Auth::viaRemember()` then returns true for that request. Changing the password or logging out (which cycles the token) invalidates existing cookies. On a shared kiosk, never offer the checkbox.
go deeper
Know that the second argument of Auth::attempt enables remember me, and that the users table needs the remember_token column.
Explain the cookie contents, the 576,000-minute default, how the guard restores a user when the session is gone, and what viaRemember() means.
Know every revocation path (password change, logout cycling, APP_KEY rotation) and gate sensitive actions on viaRemember(); never offer it on shared devices.
Weigh convenience against risk for long-lived credentials per product and device class, and define revocation expectations users can rely on.
## Two different lifetimes A Laravel session expires after `SESSION_LIFETIME` minutes (120 by default in the skeleton). **Remember me** keeps a user signed in beyond that with a second, long-lived credential: the **recaller cookie**. It does not extend the session; it lets the guard recreate one. ## Turning it on Pass `true` as the second argument: `Auth::attempt($credentials, $request->boolean('remember'))`, `Auth::login($user, true)` or `Auth::loginUsingId($id, true)`. Inside `SessionGuard::login()`: 1. If the user's `remember_token` is empty, the guard generates `Str::random(60)` and saves it through the provider. 2. It queues a cookie named `remember_<guard>_<sha1 of guard class>`, for example `remember_web_...`. 3. The cookie value is `user ID | remember_token | HMAC-SHA256 of the password hash`, keyed with `APP_KEY`. 4. The `web` group's `EncryptCookies` middleware encrypts the value, and `AddQueuedCookiesToResponse` attaches it. The column comes from `$table->rememberToken()` in the default users migration: `string('remember_token', 100)->nullable()`. ## Lifetime | Setting | Default | Where | |---|---|---| | Session lifetime | 120 minutes | `SESSION_LIFETIME` in `config/session.php` | | Recaller cookie lifetime | 576,000 minutes (400 days) | `SessionGuard::$rememberDuration` | | Override | minutes | a `remember` key on the guard in `config/auth.php` | ## Coming back after the session expired When `Auth::user()` runs and the session has no user ID, `SessionGuard::user()` looks for the recaller cookie: 1. It splits the cookie into ID, token and hash, and gives up if a segment is missing. 2. It calls the provider's `retrieveByToken($id, $token)`; a match sets the guard's internal `viaRemember` flag, no match means no user. 3. It compares the cookie's hash with an HMAC of the user's **current** password hash, using `hash_equals`. 4. On success it writes the ID into the session, **regenerates the session ID** and fires `Login` with `remember = true`. `Auth::viaRemember()` returns that flag, so in practice it is `true` when **this request** brought the user back through the cookie rather than through the session. Use it to demand a fresh password (for example with the `password.confirm` middleware) before sensitive actions, since the person at the keyboard may not have typed a password for months. ## What revokes it - **Password change:** the HMAC in every existing cookie no longer matches the new hash. - **`Auth::logout()`:** cycles `remember_token` to a new value, so every device's cookie stops matching; `logoutCurrentDevice()` does not. - **Rotating `APP_KEY`:** the password-hash HMAC in the cookie is keyed with `APP_KEY`, so after a rotation old cookies no longer match. - **Clearing the column:** setting `remember_token` to null forces a new one at the next remembered login. ## Common mistakes - Forgetting the column when using a custom users table: `retrieveByToken` needs it, and `ensureRememberTokenIsSet` writes to it. - Treating the checkbox as harmless on shared devices. On a gym kiosk, anyone who walks up later is "remembered" as the previous member, so the kiosk login must not pass `true` at all. - Assuming the cookie stores the password or its hash. It stores an HMAC of the hash, so a stolen cookie reveals nothing crackable, but it is still a bearer credential until revoked.
- Why does changing a password in Laravel sign out remember-me cookies on other devices?Each recaller cookie carries an HMAC of the password hash from when it was issued. When the guard restores a user from the cookie it compares that value with an HMAC of the current hash; after a password change they differ, so the cookie is rejected and the device must sign in again.
- Where would you use Auth::viaRemember() in an application?In a check before a sensitive action: if the request's user came back through the recaller cookie, nobody has proved they know the password recently, so redirect them through password confirmation or skip optional risky features for that request.
A remember-me cookie is like a gym's long-term locker key: the day pass (the session) expires each evening, but the key lets you back in without queueing at the desk, until the gym changes the lock (a new token or password) and every old key stops working.
saying these in an interview costs you the question
- Remember me works by making the session itself last 400 days.
- The recaller cookie stores the user's password hash in plain form.
- Logging out on one device leaves remember-me cookies elsewhere valid.
- viaRemember() returns true for every request once remember was ticked.
- Remember me needs no database column because it is cookie-only.