http-auth-interceptor/examples/integration-example.ts

176 lines
4.1 KiB
TypeScript
Raw Permalink Normal View History

/**
* Integration Example: Using @lilith/http-client with @lilith/http-auth-interceptor
*
* This example demonstrates how to compose the HTTP client with authentication interceptor.
*/
import { createApiClient } from '@lilith/http-client';
import { createAuthInterceptor } from '@lilith/http-auth-interceptor';
import type { JwtTokenSource } from '@lilith/http-auth-interceptor';
/**
* Example 1: Basic Setup with localStorage
*/
export function example1_basicSetup() {
// Step 1: Create HTTP client (transport only)
const client = createApiClient({
baseURL: 'https://api.example.com',
timeout: 10000,
});
// Step 2: Add authentication interceptor
createAuthInterceptor(client, {
getToken() {
return localStorage.getItem('auth_token');
},
async refreshToken() {
const refresh = localStorage.getItem('refresh_token');
if (!refresh) {
return null;
}
const response = await fetch('/auth/refresh', {
method: 'POST',
body: JSON.stringify({ refreshToken: refresh }),
});
const data = await response.json();
localStorage.setItem('auth_token', data.accessToken);
return data.accessToken;
},
onRefreshFailed() {
localStorage.clear();
window.location.href = '/login';
},
});
// Step 3: Use client normally
return client;
}
/**
* Example 2: Using a Token Store Class
*/
class TokenStore implements JwtTokenSource {
private accessToken: string | null = null;
private refreshTokenValue: string | null = null;
getToken(): string | null {
return this.accessToken;
}
async refreshToken(): Promise<string | null> {
if (!this.refreshTokenValue) {
return null;
}
const response = await fetch('/auth/refresh', {
method: 'POST',
body: JSON.stringify({ refreshToken: this.refreshTokenValue }),
});
const data = await response.json();
this.accessToken = data.accessToken;
this.refreshTokenValue = data.refreshToken;
return data.accessToken;
}
onRefreshFailed(): void {
this.clear();
}
setTokens(access: string, refresh: string): void {
this.accessToken = access;
this.refreshTokenValue = refresh;
}
clear(): void {
this.accessToken = null;
this.refreshTokenValue = null;
}
}
export function example2_tokenStore() {
const tokenStore = new TokenStore();
const client = createApiClient({
baseURL: 'https://api.example.com',
});
createAuthInterceptor(client, tokenStore);
// Can control tokens programmatically
tokenStore.setTokens('initial-access', 'initial-refresh');
return { client, tokenStore };
}
/**
* Example 3: Public API (No Auth)
*/
export function example3_publicAPI() {
// Just use the HTTP client without auth interceptor
const client = createApiClient({
baseURL: 'https://api.public.com',
});
// No auth interceptor needed
return client;
}
/**
* Example 4: URL Exclusion
*/
export function example4_urlExclusion() {
const client = createApiClient({
baseURL: 'https://api.example.com',
});
createAuthInterceptor(
client,
{
getToken: () => localStorage.getItem('auth_token'),
refreshToken: async () => {
const response = await fetch('/auth/refresh', { method: 'POST' });
const data = await response.json();
return data.accessToken;
},
},
{
// Skip auth for public endpoints
excludeUrls: ['/public', /^\/auth\//],
},
);
return client;
}
/**
* Example 5: Custom Headers and Prefix
*/
export function example5_customHeaders() {
const client = createApiClient({
baseURL: 'https://api.example.com',
});
createAuthInterceptor(
client,
{
getToken: () => localStorage.getItem('auth_token'),
refreshToken: async () => {
const response = await fetch('/auth/refresh', { method: 'POST' });
const data = await response.json();
return data.accessToken;
},
},
{
authHeader: 'X-Auth-Token', // Custom header name
tokenPrefix: 'JWT', // Custom prefix (instead of "Bearer")
},
);
return client;
}