CsrfService
Package: @nauth-toolkit/core
Type: Service
Generates and validates CSRF tokens for protection against cross-site request forgery attacks. Used automatically when tokenDelivery.method is 'cookies' or 'hybrid'.
- NestJS
- Express
- Fastify
import { CsrfService } from '@nauth-toolkit/nestjs';
import { CsrfService } from '@nauth-toolkit/core';
import { CsrfService } from '@nauth-toolkit/core';
Overview
Provides CSRF protection for cookie-based authentication. Generates cryptographically secure tokens and validates them using constant-time comparison. Only active when tokenDelivery.method is 'cookies' or 'hybrid'.
Auto-injected by framework adapters. CSRF protection is handled automatically by middleware when using the framework's CSRF handler/interceptor.
CSRF protection is only enabled when:
tokenDelivery.methodis'cookies'or'hybrid'- Request method is NOT
GET,HEAD, orOPTIONS(safe methods) - Route is NOT marked as public (
@Public()decorator ornauthPublicattribute) - Path is NOT in
security.csrf.excludedPathsconfiguration
For JSON token delivery, CSRF protection is not needed (tokens are not in cookies).
Methods
generateToken()
Generate a new cryptographically secure CSRF token.
generateToken(): string
Returns
string- CSRF token (64-character hexadecimal string)
Behavior
- Uses
crypto.randomBytes(32)for cryptographically secure randomness - Token length is fixed at 64 characters (32 bytes as hex)
Errors
Errors: None. This method never throws errors.
Example
- NestJS
- Express
- Fastify
@Injectable()
export class MyService {
constructor(private csrfService: CsrfService) {}
example() {
const token = this.csrfService.generateToken();
// Returns: 'a1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef123456'
}
}
app.get('/csrf-token', (req, res) => {
const token = nauth.csrfService.generateToken();
res.json({ csrfToken: token });
});
fastify.get(
'/csrf-token',
nauth.adapter.wrapRouteHandler(async () => {
const token = nauth.csrfService.generateToken();
return { csrfToken: token };
}),
);
getCookieName()
Get the configured CSRF cookie name.
getCookieName(): string
Returns
string- Cookie name (default:'nauth_csrf_token')
Behavior
- Returns the cookie name configured in
security.csrf.cookieName - Defaults to
'nauth_csrf_token'if not configured
Errors
Errors: None. This method never throws errors.
Example
- NestJS
- Express
- Fastify
const cookieName = this.csrfService.getCookieName();
// Returns: 'nauth_csrf_token' (or configured value)
const cookieName = nauth.csrfService.getCookieName();
const cookieName = nauth.csrfService.getCookieName();
getCookieOptions()
Get the cookie options used when setting the CSRF cookie.
getCookieOptions(): NAuthCookieOptions
Returns
NAuthCookieOptions- Cookie options object as configured insecurity.csrf.cookieOptions. Fields depend on what is set in config, for example:httpOnly?: booleansecure?: booleansameSite?: 'strict' | 'lax' | 'none'domain?: stringpath?: stringmaxAge?: numberexpires?: Date
Behavior
- Returns the cookie options set in
security.csrf.cookieOptions(defaults to an empty object{}if not configured) - Does not merge with
tokenDelivery.cookieOptions— onlysecurity.csrf.cookieOptionsis used - Any overrides such as
httpOnly: falseorpath: '/'must be applied by the caller when setting the cookie
Errors
Errors: None. This method never throws errors.
Example
- NestJS
- Express
- Fastify
const options = this.csrfService.getCookieOptions();
// Returns: { httpOnly: false, secure: true, sameSite: 'strict', path: '/' }
const options = nauth.csrfService.getCookieOptions();
const options = nauth.csrfService.getCookieOptions();
getHeaderName()
Get the configured CSRF header name.
getHeaderName(): string
Returns
string- Header name (default:'x-csrf-token')
Behavior
- Returns the header name configured in
security.csrf.headerName - Defaults to
'x-csrf-token'if not configured - Client should send token in this header or in body fields:
_csrforcsrfToken
Errors
Errors: None. This method never throws errors.
Example
- NestJS
- Express
- Fastify
const headerName = this.csrfService.getHeaderName();
// Returns: 'x-csrf-token' (or configured value)
const headerName = nauth.csrfService.getHeaderName();
const headerName = nauth.csrfService.getHeaderName();
validateToken()
Validate CSRF token by comparing header token with cookie token. Uses constant-time comparison to prevent timing attacks.
validateToken(headerToken: string, cookieToken: string): boolean
Parameters
headerToken- Token from request header or bodycookieToken- Token from cookie
Returns
boolean-trueif tokens match,falseotherwise
Behavior
- Returns
falseif either token is missing or empty - Uses
crypto.timingSafeEqual()for constant-time comparison - Prevents timing attacks that could reveal token values
Errors
Errors: None. This method never throws errors (returns false on validation failure).
Example
- NestJS
- Express
- Fastify
@Post('/endpoint')
async createResource(@Req() req: Request) {
const headerName = this.csrfService.getHeaderName();
const cookieName = this.csrfService.getCookieName();
const headerToken = req.headers[headerName] || req.body?._csrf;
const cookieToken = req.cookies?.[cookieName];
if (!this.csrfService.validateToken(String(headerToken || ''), cookieToken || '')) {
throw new NAuthException(AuthErrorCode.CSRF_TOKEN_INVALID, 'CSRF token validation failed');
}
}
app.post('/endpoint', (req, res) => {
const headerName = nauth.csrfService.getHeaderName();
const cookieName = nauth.csrfService.getCookieName();
const headerToken = req.headers[headerName] || req.body?._csrf;
const cookieToken = req.cookies?.[cookieName];
if (!nauth.csrfService.validateToken(String(headerToken || ''), cookieToken || '')) {
return res.status(403).json({ error: 'CSRF token invalid' });
}
res.json({ success: true });
});
fastify.post(
'/endpoint',
nauth.adapter.wrapRouteHandler(async (req) => {
const headerName = nauth.csrfService.getHeaderName();
const cookieName = nauth.csrfService.getCookieName();
const headerToken = req.headers[headerName] || req.body?._csrf;
const cookieToken = req.cookies?.[cookieName];
if (!nauth.csrfService.validateToken(String(headerToken || ''), cookieToken || '')) {
throw new NAuthException(AuthErrorCode.CSRF_TOKEN_INVALID, 'CSRF token validation failed');
}
return { success: true };
}),
);
Manual Usage
If you're not using the framework's CSRF middleware/interceptor, you can manually control CSRF protection:
Token Generation (GET requests):
- NestJS
- Express
- Fastify
@Get('/csrf-token')
getCsrfToken(@Res() res: Response) {
const token = this.csrfService.generateToken();
const cookieName = this.csrfService.getCookieName();
const cookieOptions = this.csrfService.getCookieOptions();
res.cookie(cookieName, token, {
...cookieOptions,
httpOnly: false,
path: '/',
});
res.setHeader(this.csrfService.getHeaderName(), token);
return { csrfToken: token };
}
app.get('/csrf-token', (req, res) => {
const token = nauth.csrfService.generateToken();
const cookieName = nauth.csrfService.getCookieName();
const cookieOptions = nauth.csrfService.getCookieOptions();
res.cookie(cookieName, token, {
...cookieOptions,
httpOnly: false,
path: '/',
});
res.setHeader(nauth.csrfService.getHeaderName(), token);
res.json({ csrfToken: token });
});
fastify.get(
'/csrf-token',
nauth.adapter.wrapRouteHandler(async (req, res) => {
const token = nauth.csrfService.generateToken();
const cookieName = nauth.csrfService.getCookieName();
const cookieOptions = nauth.csrfService.getCookieOptions();
res.setCookie(cookieName, token, {
...cookieOptions,
httpOnly: false,
path: '/',
});
res.header(nauth.csrfService.getHeaderName(), token);
return { csrfToken: token };
}),
);
Token Validation (POST/PUT/DELETE/PATCH requests):
See validateToken() example above.
Related APIs
- CsrfGuard - NestJS guard for CSRF protection
- Token Delivery Modes - When CSRF protection is active
- Password & Security Configuration - CSRF configuration options