Configuration
Complete guide to configuring @nauth-toolkit/client for your application.
Basic Configuration
- Vanilla JS/TS
- Angular
import { NAuthClient } from '@nauth-toolkit/client';
const client = new NAuthClient({
baseUrl: 'https://api.example.com/auth',
tokenDelivery: 'cookies',
onSessionExpired: () => {
window.location.replace('/login');
},
});
See NAuthClientConfig for complete interface.
import { inject } from '@angular/core';
import { Router } from '@angular/router';
import { NAUTH_CLIENT_CONFIG } from '@nauth-toolkit/client-angular';
export const appConfig = {
providers: [
{
provide: NAUTH_CLIENT_CONFIG,
useFactory: () => {
const router = inject(Router);
return {
baseUrl: 'https://api.example.com/auth',
tokenDelivery: 'cookies',
onSessionExpired: () => router.navigate(['/login']),
};
},
},
],
};
Required Options
| Option | Type | Description |
|---|---|---|
baseUrl | string | Backend auth API URL |
tokenDelivery | 'json' | 'cookies' | Token delivery mode (must match backend). See Token Management |
onSessionExpired | () => void | Callback when session expires |
See NAuthClientConfig for all options.
Token Delivery Modes
Cookies (Web Applications)
{
baseUrl: 'https://api.example.com/auth',
tokenDelivery: 'cookies',
}
- Tokens stored in HTTP-only cookies (server-managed)
- Automatic CSRF protection required
- Interceptor adds
withCredentials: true - Most secure option for web browsers
JSON (Mobile/Native Apps)
{
baseUrl: 'https://api.example.com/mobile/auth', // Different endpoint for mobile
tokenDelivery: 'json',
}
- Tokens returned in response body
- Stored in provided storage adapter (secure storage recommended)
- Interceptor adds
Authorization: Bearerheader - Required for Capacitor, React Native, etc.
When your backend supports both web and mobile apps (hybrid deployment), it exposes separate endpoints for each delivery mode:
- Web (cookies):
/auth/* - Mobile (JSON):
/mobile/auth/*
The frontend chooses ONE mode based on the platform and uses the appropriate baseUrl.
See Token Delivery for backend setup.
CSRF Configuration
Required for cookies mode:
{
tokenDelivery: 'cookies',
csrf: {
cookieName: 'nauth_csrf_token', // Default
headerName: 'x-csrf-token', // Default
},
}
The interceptor automatically:
- Reads CSRF token from cookie
- Attaches to
POST,PUT,PATCH,DELETErequests
CSRF cookie and header names must match your backend configuration.
reCAPTCHA Configuration
When your backend enforces reCAPTCHA (e.g., for login/signup), configure the client to send tokens:
{
baseUrl: 'https://api.example.com/auth',
tokenDelivery: 'cookies',
recaptcha: {
enabled: true,
version: 'enterprise', // 'v2' | 'v3' | 'enterprise' - must match backend
siteKey: '6Le...your-site-key',
action: 'submit', // Optional: fallback action. Angular SDK auto-passes 'login'/'signup' per-endpoint.
autoLoadScript: true, // Optional: preload script at startup (default: true for v3/Enterprise)
},
}
- Angular: Use
provideRecaptcha({ enabled, version, siteKey })from@nauth-toolkit/client-angularin addition torecaptchainNAUTH_CLIENT_CONFIG. The SDK auto-generates and attaches tokens for v3/Enterprise, using'login'and'signup'as the action for their respective API calls. - Vanilla/React/Vue: Load the reCAPTCHA script, call
grecaptcha.execute()(orgrecaptcha.enterprise.execute()for Enterprise) before login/signup, and pass the token toclient.login()/client.signup().
See reCAPTCHA Guide and NAuthClientConfig for full options.
Custom Storage
By default, uses localStorage in browser. Provide custom adapter for:
- Mobile apps (Capacitor, React Native)
- SSR (in-memory or server-side storage)
- Session storage
import { NAuthClient, InMemoryStorage, BrowserStorage } from '@nauth-toolkit/client';
// Session storage instead of local storage
const client = new NAuthClient({
baseUrl: 'https://api.example.com/auth',
tokenDelivery: 'json',
storage: new BrowserStorage(window.sessionStorage),
onSessionExpired: () => {},
});
// In-memory for SSR
const ssrClient = new NAuthClient({
baseUrl: 'https://api.example.com/auth',
tokenDelivery: 'json',
storage: new InMemoryStorage(),
onSessionExpired: () => {},
});
See NAuthClientConfig for storage adapters.
Custom Storage Adapter
import { NAuthStorageAdapter } from '@nauth-toolkit/client';
import { Preferences } from '@capacitor/preferences';
class CapacitorStorage implements NAuthStorageAdapter {
async getItem(key: string): Promise<string | null> {
const { value } = await Preferences.get({ key });
return value;
}
async setItem(key: string, value: string): Promise<void> {
await Preferences.set({ key, value });
}
async removeItem(key: string): Promise<void> {
await Preferences.remove({ key });
}
async clear(): Promise<void> {
await Preferences.clear();
}
}
const client = new NAuthClient({
baseUrl: 'https://api.example.com/auth',
tokenDelivery: 'json',
storage: new CapacitorStorage(),
onSessionExpired: () => {},
});
Callbacks
onAuthResponse
Custom handler for all authentication responses. Overrides automatic navigation. Perfect for dialog-based flows:
{
onAuthResponse: (response, context) => {
// context.source: 'login' | 'signup' | 'social' | 'challenge'
if (response.challengeName) {
// Handle challenge (dialog, modal, or custom navigation)
dialog.open(ChallengeComponent, {
data: { challenge: response, source: context.source }
});
} else if (response.user) {
// Authentication complete
router.navigate(['/dashboard']);
}
},
}
When to use:
- Dialog/modal-based challenge flows
- Custom navigation logic
- Complex UI state management
When onAuthResponse is provided, the SDK skips automatic navigation. You control all routing.
navigationHandler
Custom navigation function. Use your framework's router instead of window.location:
{
navigationHandler: (url: string) => {
// Angular
inject(Router).navigateByUrl(url);
// React Router
navigate(url);
// Vue Router
router.push(url);
},
}
Default behavior:
- Guards:
window.location.replace(url) - Other contexts:
window.location.href = url
onSessionExpired
Called when refresh fails (401 after refresh attempt):
{
onSessionExpired: () => {
// Clear app state
appState.reset();
// Redirect to login
window.location.replace('/login');
},
}
onAuthStateChange
Called when auth state changes (login, logout, token refresh):
{
onAuthStateChange: (user) => {
if (user) {
analytics.identify(user.sub);
} else {
analytics.reset();
}
},
}
onTokenRefresh
Called after successful token refresh:
{
onTokenRefresh: () => {
console.log('Tokens refreshed at', new Date());
},
}
onError
Global error handler:
{
onError: (error) => {
// Log to monitoring service
Sentry.captureException(error);
// Handle specific errors
if (error.code === 'NETWORK_ERROR') {
showToast('Network error. Please check your connection.');
}
},
}
Custom Endpoints
Override default endpoint paths:
{
baseUrl: 'https://api.example.com/auth',
tokenDelivery: 'cookies',
endpoints: {
login: '/signin',
signup: '/register',
logout: '/signout',
refresh: '/token/refresh',
profile: '/me',
},
onSessionExpired: () => {},
}
All Available Endpoints
To override or customize API endpoint paths, your backend must implement these endpoints according to the NAuth specification. Otherwise, authentication flows will fail. all endpoint paths listed below should be present and correctly handle the expected request/response formats.
See the API Reference for type requirements.
| Key | Default | Description |
|---|---|---|
login | /login | Login endpoint |
signup | /signup | Signup endpoint |
logout | /logout | Logout endpoint |
logoutAll | /logout/all | Logout all sessions |
refresh | /refresh | Token refresh |
respondChallenge | /respond-challenge | Challenge response |
resendCode | /challenge/resend | Resend verification code |
getSetupData | /challenge/setup-data | MFA setup data |
getChallengeData | /challenge/challenge-data | Challenge data |
profile | /profile | Get profile |
updateProfile | /profile | Update profile |
changePassword | /change-password | Change password |
mfaStatus | /mfa/status | MFA status |
mfaDevices | /mfa/devices | MFA devices |
mfaSetupData | /mfa/setup-data | MFA setup |
mfaVerifySetup | /mfa/verify-setup | Verify MFA setup |
mfaRemove | /mfa/remove | Remove MFA device |
mfaPreferred | /mfa/preferred | Set preferred MFA |
mfaBackupCodes | /mfa/backup-codes | Generate backup codes |
socialRedirectStart | /social/:provider/redirect | Start web social login redirect |
socialExchange | /social/exchange | Exchange exchangeToken (json/hybrid or cookies-with-challenge) |
socialVerify | /social/:provider/verify | Verify native social |
socialLinked | /social/linked | Linked accounts |
socialLink | /social/link | Link account |
socialUnlink | /social/unlink | Unlink account |
trustDevice | /trust-device | Trust device |
auditHistory | /audit/history | Audit history |
Device Trust
Configure device trust header:
{
deviceTrust: {
headerName: 'x-device-token', // Default
storageKey: 'nauth_device_token', // Default
},
}
Custom Headers
Add headers to all requests:
{
headers: {
'X-App-Version': '1.0.0',
'X-Platform': 'web',
},
}
Request Timeout
Set request timeout in milliseconds:
{
timeout: 30000, // 30 seconds
}
Debug Mode
Enable debug logging:
{
debug: process.env.NODE_ENV === 'development',
}
Full Configuration Example
import { AuthChallenge } from '@nauth-toolkit/client';
const client = new NAuthClient({
// Required
baseUrl: 'https://api.example.com/auth',
tokenDelivery: 'cookies',
// Challenge navigation
redirects: {
loginSuccess: '/dashboard',
signupSuccess: '/onboarding',
sessionExpired: '/login',
oauthError: '/login',
challengeBase: '/auth/challenge',
// Optional: Custom routes
challengeRoutes: {
[AuthChallenge.MFA_REQUIRED]: '/auth/mfa',
},
// Optional: Single route mode
// useSingleChallengeRoute: true,
// Optional: MFA-specific routes
mfaRoutes: {
passkey: '/auth/passkey',
selector: '/auth/choose-mfa',
default: '/auth/verify-code',
},
},
// Optional: Custom navigation
navigationHandler: (url) => inject(Router).navigateByUrl(url),
// Optional: Dialog-based flow
// onAuthResponse: (response, context) => {
// if (response.challengeName) {
// dialog.open(ChallengeComponent, { data: response });
// }
// },
// CSRF (for cookies mode)
csrf: {
cookieName: 'nauth_csrf_token',
headerName: 'x-csrf-token',
},
// Callbacks
onAuthStateChange: (user) => {
if (user) analytics.identify(user.sub);
},
onTokenRefresh: () => console.log('Tokens refreshed'),
onError: (error) => Sentry.captureException(error),
// Device trust
deviceTrust: {
headerName: 'x-device-token',
storageKey: 'nauth_device',
},
// Custom headers
headers: {
'X-App-Version': APP_VERSION,
},
// Timeout
timeout: 30000,
// Debug
debug: isDevelopment,
});
Redirects and Auto-Navigation
The SDK can automatically navigate after authentication and on certain error conditions using redirects.
redirects.loginSuccess: where to navigate after successful login/social (no challenge)redirects.signupSuccess: where to navigate after successful signup (no challenge)- Legacy:
redirects.successis a deprecated alias forloginSuccess
Disable auto-navigation (events-only routing)
If you want to do all routing manually (for example in Angular by subscribing to authEvents$), set the redirect to null.
redirects: {
loginSuccess: null,
signupSuccess: null,
oauthError: null,
sessionExpired: null,
}
Notes:
- Use
nullto disable. Leaving a key undefined/omitted means “not set” and falls back to defaults. - Challenge routing (MFA, verify-email, etc.) is controlled by
challengeBase,challengeRoutes,mfaRoutes, anduseSingleChallengeRoute.
Related Documentation
- NAuthClientConfig API - Full reference
- Challenge Handling - Challenge navigation and routing
- Token Management - Token handling
- Getting Started - Setup guide