Laravel & Cookies: A Practical Guide for 2025
Cookies are one of the smallest moving parts in a web application, yet they carry a surprising amount of responsibility—remembering a user, persisting preferences, even running an entire stateless session driver. Laravel bakes in (pun intended) a full-featured, secure cookie layer so you rarely have to think about cryptography or integrity checks. This post walks you through the “what, why, and how” of cookies in modern Laravel (v11 / v12) and sprinkles in a few production-ready tips along the way.
1. What makes a Laravel cookie special?
Out of the box every cookie created by Laravel is both encrypted and signed. The framework uses your APP_KEY
to AES-encrypt the payload and attaches an HMAC so any tampering renders the cookie invalid. You don’t need to call a special method—this is the default for anything returned by the cookie()
helper, Cookie
facade, or queued via Cookie::queue()
LaravelLaravel
2. Creating cookies
In every case, the third argument is the expiration in minutes. If you want a “never expires” cookie, reach for Cookie::forever()
(internally sets a five-year expiry) WPWeb Infotech
3. Reading cookies
Inside a controller, service, or route closure, inject Illuminate\Http\Request
and call cookie()
:
If you’re outside the request cycle—or just prefer facades—Cookie::get('theme')
works the same way Tutorials Point. Because Laravel automatically decrypts and verifies the MAC, the value you receive is plain text unless decryption fails (in which case you’ll get null
).
4. Deleting cookies
Under the hood Laravel sets the same cookie name with an empty value and an expiration in the past W3Schools.
5. Tuning attributes (path, domain, SameSite, secure, httpOnly)
Every cookie()
call accepts a longer signature if you need fine-grained control:
cookie(
name: 'promo_code',
value: encrypt('FREESHIP'),
minutes: 10,
path: '/',
domain: '.example.com',
secure: true, // only HTTPS
httpOnly: true, // not accessible to JS
sameSite: 'lax' // or 'strict' / 'none'
);
Tip 🔒 : Always set secure
and an appropriate SameSite
value in production, especially if you’re authenticating across multiple sub-domains. Browsers have tightened the rules since 2024, and leaving defaults can break cross-site login flows silently.
6. Opt-out of encryption (rare, but possible)
Occasionally you must share a human-readable cookie with a third-party script. Add the cookie name to App\Http\Middleware\EncryptCookies::$except
:
class EncryptCookies extends Middleware
{
protected $except = [
'tracking_pixel',
];
}
Everything else stays encrypted Vincent Schmalbach. Make sure you’re comfortable exposing the value before doing this.
7. Key rotation & the APP_PREVIOUS_KEYS
safety net
Rotating APP_KEY
—for example during a breach drill—makes every existing encrypted cookie unreadable. As of Laravel 11 you can list earlier keys in APP_PREVIOUS_KEYS
, letting Laravel attempt decryption with each key in order Laravel. Gradually migrate users without forcing everyone to log in again.
8. Cookies versus sessions
-
Cookie driver: Stores the whole session payload in an encrypted cookie, making your app stateless. Great for horizontal scaling, but remember the 4 KB per-cookie size limit Laravel.
-
Other drivers (
database
,redis
, etc.): The cookie only holds a session ID; data lives server-side.
Pick the model that fits your load balancer and compliance story.
9. Common pitfalls & best practices
Pitfall | Fix |
---|---|
“My cookie disappears on refresh.” | Ensure you’re returning the same response instance that attaches/queues the cookie. |
Large payload (>4 KB). | Move to server-side sessions or split data across multiple cookies. |
Mixing signed JS cookies. | If JavaScript must read the cookie, set httpOnly = false and sign the value yourself. |
GDPR / privacy banners. | Even encrypted cookies can be “personal data.” Disclose their purpose and expiration. |
10. Final thoughts
Laravel’s philosophy is to keep the tedious parts of web security invisible so you can focus on writing features. Cookies exemplify that approach: encrypted by default, easy to add, and just as easy to delete or ignore. Keep an eye on the size limit, rotate your keys responsibly, and you’ll bake reliable state into your app with minimal effort.
Happy crafting—and don’t forget to clear your browser cache after testing! 🍪
Laravel Cookies – Top 10 FAQs
# | Question | Short Answer |
---|---|---|
1 | How do I create a cookie in Laravel? | Use the cookie() helper or the Cookie facade: return response('ok')->cookie('name', 'value', 30); (30 minutes). |
2 | Are cookies encrypted by default? | Yes. Anything set via Laravel’s cookie helpers is AES-encrypted and signed with your APP_KEY . |
3 | Where do I read a cookie value? | Inside a controller or route: $value = $request->cookie('name'); or Cookie::get('name'); . |
4 | How do I delete a cookie? | Queue a “forget” cookie: Cookie::queue(Cookie::forget('name')); or include it on the same response with .withoutCookie('name') . |
5 | What’s the max size for a cookie? | Roughly 4 KB (browser limit). If you hit that, switch to a server-side session driver. |
6 | Can I stop a specific cookie from being encrypted? | Yes—add its name to EncryptCookies::$except middleware. Use sparingly because it removes encryption and integrity checks. |
7 | How do I set SameSite or Secure attributes? | Pass extra arguments: cookie('promo', 'ABC', 10, '/', null, true, true, false, 'strict'); (secure , httpOnly , raw , sameSite ). |
8 | What happens after I rotate APP_KEY? | Existing encrypted cookies break. Add old keys to APP_PREVIOUS_KEYS so Laravel can still decrypt them during the transition. |
9 | Can I store the whole session in a cookie? | Yes—set SESSION_DRIVER=cookie , but mind the 4 KB limit and avoid storing sensitive/user-editable data. |
10 | Why does my cookie vanish on the next request? | Make sure you return or send the same response instance that you called ->cookie() or Cookie::queue() on; otherwise the header never reaches the browser. |