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-toolkit 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