@dfsync/client supports three auth strategies:
- bearer token
- API key
- custom auth
Auth is configured once at client creation time.
const client = createClient({
baseUrl: 'https://api.example.com',
auth: {
type: 'bearer',
token: 'secret-token',
},
});This adds:
authorization: Bearer secret-tokenYou can resolve the token lazily:
const client = createClient({
baseUrl: 'https://api.example.com',
auth: {
type: 'bearer',
token: async () => {
return process.env.API_TOKEN!;
},
},
});const client = createClient({
baseUrl: 'https://api.example.com',
auth: {
type: 'bearer',
token: 'secret-token',
headerName: 'x-authorization',
},
});By default, API key auth uses header mode and the header name x-api-key.
const client = createClient({
baseUrl: 'https://api.example.com',
auth: {
type: 'apiKey',
value: 'api-key-123',
},
});This adds:
x-api-key: api-key-123const client = createClient({
baseUrl: 'https://api.example.com',
auth: {
type: 'apiKey',
value: async () => {
return process.env.API_KEY!;
},
},
});const client = createClient({
baseUrl: 'https://api.example.com',
auth: {
type: 'apiKey',
value: 'api-key-123',
name: 'x-service-key',
},
});const client = createClient({
baseUrl: 'https://api.example.com',
auth: {
type: 'apiKey',
value: 'query-key',
in: 'query',
name: 'api_key',
},
});A request like:
await client.get('/users', {
query: { page: 1 },
});becomes:
https://api.example.com/users?page=1&api_key=query-key
Use custom auth when you need full control over headers and URL mutation.
const client = createClient({
baseUrl: 'https://api.example.com',
auth: {
type: 'custom',
apply: ({ headers, url, request }) => {
headers['x-service-name'] = 'billing-worker';
url.searchParams.set('tenant', 'acme');
},
},
});Custom auth receives:
request, url, headers
This lets you inspect the request and modify the final URL or headers before the request is sent.
Auth runs before beforeRequest hooks.
That means beforeRequest hooks can see and further modify headers or query params already produced by auth.
If auth writes to a header that already exists, auth wins.
Example:
const client = createClient({
baseUrl: 'https://api.example.com',
headers: {
authorization: 'Bearer old-token',
},
auth: {
type: 'bearer',
token: 'new-token',
},
});Final header:
authorization: Bearer new-tokentype AuthValueResolver = string | (() => string | Promise<string>);
type BearerAuthConfig = {
type: 'bearer';
token: AuthValueResolver;
headerName?: string;
};
type ApiKeyAuthConfig = {
type: 'apiKey';
value: AuthValueResolver;
in?: 'header' | 'query';
name?: string;
};
type CustomAuthConfig = {
type: 'custom';
apply: (ctx: {
request: RequestConfig;
url: URL;
headers: Record<string, string>;
}) => void | Promise<void>;
};- internal service authentication
- bearer tokens
- API tokens
- integration services
Centralizing authentication inside the client configuration provides:
- consistent authentication across requests
- cleaner application code
- easier token rotation or refresh logic
Keep auth logic centralized in the client configuration instead of repeating it in every request.