- Home
- HTTP Headers
- Set-Cookie
Header
Set-Cookie
Learn how the Set-Cookie header instructs browsers to store cookies with attributes like HttpOnly, Secure, SameSite, and expiration settings.
TL;DR: Creates or updates cookies in the browser with specified attributes. Use HttpOnly, Secure, and SameSite for security, especially for session cookies.
What is Set-Cookie?
Set-Cookie tells the browser to store a small piece of data (a cookie) that will be sent back with future requests to the same domain. It’s like giving someone a membership card - they show it every time they visit to prove who they are or maintain their preferences.
Cookies are essential for user sessions, preferences, shopping carts, and tracking.
How It Works
1. Server sends cookie in response:
HTTP/1.1 200 OK
Set-Cookie: sessionId=abc123; Path=/; HttpOnly; Secure
Content-Type: text/html
<html>Welcome back!</html>
```text
**2. Browser stores the cookie.**
**3. Browser sends cookie with future requests:**
```http
GET /dashboard HTTP/1.1
Host: example.com
Cookie: sessionId=abc123
4. Server recognizes the user and provides personalized content.
Basic Syntax
Set-Cookie: name=value; attribute1; attribute2=value2
```text
### Simple Cookie
```http
Set-Cookie: username=john
Cookie with Attributes
Set-Cookie: sessionId=abc123; Path=/; Domain=example.com; Secure; HttpOnly; SameSite=Strict
```text
## Cookie Attributes
### Path
Restricts cookie to specific URL paths:
```http
Set-Cookie: adminToken=xyz789; Path=/admin
Cookie only sent for /admin/* URLs.
Domain
Restricts cookie to specific domain/subdomains:
Set-Cookie: userId=123; Domain=example.com
```text
Cookie sent to `example.com` and `*.example.com`.
### Expires
Sets absolute expiration date:
```http
Set-Cookie: rememberMe=true; Expires=Wed, 15 Jan 2026 12:00:00 GMT
Max-Age
Sets relative expiration in seconds:
Set-Cookie: sessionId=abc123; Max-Age=3600
```text
Cookie expires in 1 hour.
### Secure
Only send over HTTPS:
```http
Set-Cookie: sensitiveData=secret; Secure
HttpOnly
Prevent JavaScript access:
Set-Cookie: sessionId=abc123; HttpOnly
```text
Protects against XSS attacks.
### SameSite
Controls cross-site request behavior:
```http
Set-Cookie: csrfToken=xyz; SameSite=Strict
Real-World Examples
User Session
Set-Cookie: sessionId=a1b2c3d4e5f6; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=86400
```text
Secure session cookie that expires in 24 hours.
### User Preferences
```http
Set-Cookie: theme=dark; Path=/; Max-Age=31536000; SameSite=Lax
Theme preference stored for 1 year.
Shopping Cart
Set-Cookie: cartId=cart_789; Path=/; Max-Age=604800; SameSite=Lax
```text
Shopping cart ID stored for 1 week.
### Remember Me
```http
Set-Cookie: rememberToken=longRandomString; Path=/; HttpOnly; Secure; SameSite=Strict; Max-Age=2592000
Long-term authentication token for 30 days.
CSRF Protection
Set-Cookie: csrfToken=randomToken123; Path=/; SameSite=Strict; Secure
```text
CSRF token that's only sent with same-site requests.
## Multiple Cookies
Send multiple cookies with separate headers:
```http
HTTP/1.1 200 OK
Set-Cookie: sessionId=abc123; HttpOnly; Secure
Set-Cookie: theme=dark; Max-Age=31536000
Set-Cookie: language=en; Path=/; Max-Age=31536000
Content-Type: text/html
Cookie Security
Secure Cookies
Always use Secure for sensitive data:
✅ Set-Cookie: sessionId=abc123; Secure; HttpOnly
❌ Set-Cookie: sessionId=abc123
```text
### HttpOnly Protection
Prevent XSS cookie theft:
```http
✅ Set-Cookie: sessionId=abc123; HttpOnly
❌ Set-Cookie: sessionId=abc123 (accessible via JavaScript)
SameSite Protection
Prevent CSRF attacks:
Set-Cookie: sessionId=abc123; SameSite=Strict # Strictest
Set-Cookie: sessionId=abc123; SameSite=Lax # Balanced
Set-Cookie: sessionId=abc123; SameSite=None; Secure # Cross-site (requires Secure)
```text
## Cookie Expiration
### Session Cookies
No expiration - deleted when browser closes:
```http
Set-Cookie: tempData=value
Persistent Cookies
With expiration date:
Set-Cookie: userData=value; Max-Age=86400
```text
### Delete Cookies
Set expiration in the past:
```http
Set-Cookie: oldCookie=; Expires=Thu, 01 Jan 1970 00:00:00 GMT; Path=/
Server Implementation
Express.js
app.get('/login', (req, res) => {
// Set secure session cookie
res.cookie('sessionId', 'abc123', {
httpOnly: true,
secure: true,
sameSite: 'strict',
maxAge: 24 * 60 * 60 * 1000 // 24 hours
})
res.json({ message: 'Logged in successfully' })
})
// Delete cookie
app.post('/logout', (req, res) => {
res.clearCookie('sessionId', {
httpOnly: true,
secure: true,
sameSite: 'strict'
})
res.json({ message: 'Logged out' })
})
```javascript
### Python Flask
```python
from flask import make_response
@app.route('/login')
def login():
response = make_response('Logged in')
response.set_cookie(
'sessionId',
'abc123',
max_age=86400,
secure=True,
httponly=True,
samesite='Strict'
)
return response
Best Practices
1. Always use Secure for sensitive cookies:
Set-Cookie: sessionId=abc123; Secure; HttpOnly
```text
**2. Use HttpOnly for session cookies:**
```http
Set-Cookie: sessionId=abc123; HttpOnly
3. Set appropriate SameSite:
Set-Cookie: sessionId=abc123; SameSite=Strict # For auth
Set-Cookie: preferences=theme; SameSite=Lax # For UX
```text
**4. Use reasonable expiration times:**
```text
Session cookies: No expiration (browser session)
Auth tokens: 1-24 hours
Preferences: 30 days to 1 year
Remember me: 30 days maximum
```text
**5. Minimize cookie size:**
```text
Keep cookies under 4KB total per domain
Store large data server-side, use cookie as key
```text
**6. Use descriptive names:**
```http
✅ Set-Cookie: userSessionId=abc123
❌ Set-Cookie: s=abc123
Common Issues
Problem: Cookie not being sent Solution: Check Path, Domain, Secure, and SameSite attributes
Problem: Cookie accessible via JavaScript
Solution: Add HttpOnly attribute
Problem: Cookie sent over HTTP
Solution: Add Secure attribute and use HTTPS
Problem: CSRF attacks
Solution: Use SameSite=Strict or SameSite=Lax
Related Headers
- Cookie - Request header that sends stored cookies
- Cache-Control - Affects cookie caching
- Vary - Cache different responses based on cookies
In Practice
Express.js
// Session cookie (deleted when browser closes)
res.cookie('sessionId', token, {
httpOnly: true,
secure: true,
sameSite: 'lax',
path: '/'
})
// Persistent cookie (30 days)
res.cookie('rememberMe', userId, {
httpOnly: true,
secure: true,
sameSite: 'strict',
maxAge: 30 * 24 * 60 * 60 * 1000 // ms
})
// Clear a cookie
res.clearCookie('sessionId', { path: '/' })Next.js App Router
import { cookies } from 'next/headers'
// Server Action or Route Handler
export async function POST(request: Request) {
const cookieStore = await cookies()
// Set session cookie
cookieStore.set('sessionId', token, {
httpOnly: true,
secure: true,
sameSite: 'lax',
path: '/'
})
// Or via Response headers
return new Response(null, {
status: 200,
headers: {
'Set-Cookie': 'sessionId=abc123; Path=/; HttpOnly; Secure; SameSite=Lax'
}
})
}Django
from django.http import JsonResponse
def login_view(request):
response = JsonResponse({'status': 'ok'})
# Session cookie
response.set_cookie(
'sessionId',
value=token,
httponly=True,
secure=True,
samesite='Lax',
path='/'
)
# Persistent cookie (30 days)
response.set_cookie(
'rememberMe',
value=user_id,
max_age=30 * 24 * 60 * 60,
httponly=True,
secure=True,
samesite='Strict'
)
return responseFrequently Asked Questions
What is Set-Cookie?
Set-Cookie is a response header that creates or updates cookies in the browser. It specifies the cookie name, value, and attributes like expiration, domain, and security settings.
What cookie attributes should I use for security?
Use HttpOnly to prevent JavaScript access, Secure to require HTTPS, SameSite=Strict or Lax to prevent CSRF. For session cookies, combine all three.
How do I set a cookie expiration?
Use Max-Age (seconds) or Expires (date). Max-Age=3600 expires in 1 hour. Without either, the cookie is a session cookie deleted when the browser closes.
Can I set multiple cookies in one response?
Yes, use multiple Set-Cookie headers. Each header sets one cookie. You cannot combine multiple cookies in a single Set-Cookie header.