CSRF Protection
node-auth supports the double-submit cookie pattern for CSRF protection.
CSRF double-submit flow
Why this works
An attacker can force the victim's browser to send cookies (CSRF), but cannot read the csrf-token cookie value from a different origin due to the Same-Origin Policy. So they cannot set the X-CSRF-Token header — the request fails.
Enable CSRF
const config: AuthConfig = {
accessTokenSecret: '…',
refreshTokenSecret: '…',
accessTokenExpiresIn: '15m',
refreshTokenExpiresIn: '7d',
csrf: {
enabled: true,
},
};
Client-Side
Vanilla JS / Fetch
function getCsrfToken(): string {
return document.cookie
.split('; ')
.find(row => row.startsWith('csrf-token='))
?.split('=')[1] ?? '';
}
await fetch('/auth/logout', {
method: 'POST',
headers: { 'X-CSRF-Token': getCsrfToken() },
credentials: 'include',
});
Angular — handled automatically
The authInterceptor in the Angular demo reads csrf-token and adds X-CSRF-Token automatically on every POST/PUT/PATCH/DELETE. See Angular Integration.
Next.js — handled manually
const csrfToken = document.cookie.match(/(?:^|;\s*)csrf-token=([^;]+)/)?.[1] ?? '';
await fetch('/api/auth/logout', {
method: 'POST',
headers: { 'X-CSRF-Token': csrfToken },
credentials: 'include',
});
Cookie details
| Cookie | HttpOnly | Readable by JS | Purpose |
|---|---|---|---|
accessToken | ✅ | ❌ | Authenticate API requests |
refreshToken | ✅ | ❌ | Obtain new access tokens |
csrf-token | ❌ | ✅ | CSRF double-submit value |
The csrf-token cookie has the same expiry as the accessToken cookie (default 15 min) and is regenerated on every token refresh.