TL;DR
Logout isn't just deleting a cookie. You need to invalidate the session server-side, clear all auth tokens, handle "logout everywhere" scenarios, and prevent session reuse. These prompts help you implement logout that actually logs users out.
Basic Secure Logout
Implement a secure logout endpoint.
Framework: Next.js/Express/Django
Logout must:
- Invalidate session in database/store (not just cookie)
- Clear session cookie with proper attributes
- Clear any refresh tokens
- Clear remember-me tokens
- Redirect to safe page
Server-side:
- Delete session from session store
- Mark refresh tokens as revoked
- Log the logout event
Cookie clearing:
- Set cookie with same name, path, domain
- Set Max-Age=0 or expires in past
- Include Secure, HttpOnly flags
Response:
- POST request (not GET to prevent CSRF via image tags)
- Redirect to /login or home page
- Don't expose any error details
Logout All Devices
Implement "logout from all devices" functionality.
When user clicks "Logout Everywhere":
- Find all sessions for this user
- Invalidate/delete all sessions
- Revoke all refresh tokens
- Optionally keep current session
- Notify other sessions they're logged out
Implementation:
- sessions table needs user_id column
- DELETE FROM sessions WHERE user_id = ?
- Or UPDATE refresh_tokens SET revoked = true WHERE user_id = ?
If keeping current session:
- DELETE FROM sessions WHERE user_id = ? AND id != ?
Show active sessions:
- List devices/browsers with sessions
- Show last active time
- Allow selective revocation
Trigger auto-logout everywhere on:
- Password change
- Email change
- Security concern reported
Use POST for logout: GET requests can be triggered by images or links. An attacker could log users out by including on their site. Always require POST.
Client-Side Cleanup
Clean up client-side state on logout.
After successful logout API call:
Clear storage:
- localStorage.removeItem('auth_token')
- sessionStorage.clear() for sensitive data
- Clear any cached user data
Clear application state:
- Reset auth context/store to null
- Clear React Query/SWR cache for user data
- Reset any user-specific state
Redirect safely:
- window.location.href = '/login'
- Or router.push('/login') with state reset
Don't do:
- Leave tokens in memory
- Keep user data in cache
- Allow back button to show protected pages
Consider:
- Show brief "Logged out" confirmation
- Clear service worker caches if applicable
JWT Logout Considerations
Handle logout properly when using JWTs.
Challenge: JWTs are stateless, can't truly "invalidate"
Solutions:
- Short access token expiry (15 min) + revocable refresh tokens
- Token blacklist in Redis
- Token version in user record
Recommended approach (refresh tokens):
- On logout, delete refresh token from database
- Access token continues working until expiry (15 min max)
- Client deletes access token from memory
If immediate invalidation needed:
- Add jti (token ID) to blacklist in Redis
- Set TTL matching token expiration
- Check blacklist on protected routes
On logout:
- Revoke refresh token in database
- Add access token jti to blacklist
- Clear tokens from client
- Redirect to login
Pro tip: Test logout by logging in on two devices, logging out on one, and verifying the session is truly terminated. Can you still access protected pages on the logged-out device by using the back button?
Why not just clear the cookie?
If you only clear the cookie without invalidating the session server-side, someone who copied the session ID could continue using it. Always invalidate server-side first.
Should logout require authentication?
No. If the user's session is already invalid, they should still be able to "logout" (clear cookies and redirect). Handle both authenticated and unauthenticated logout gracefully.