Refresh, CSRF, and Sensitive Guards¶
These options change behavior around 401, 419, 429, and mutations. They must be documented in the consuming application.
Bearer Refresh Single-Flight¶
import { bearerAuth, bearerRefreshGuard, createHttpClient } from "@cedvict/http-guardian";
const api = createHttpClient({
baseUrl: "https://api.example.com",
auth: bearerAuth(() => tokenStore.access()),
parser,
guards: [
bearerRefreshGuard({
refreshFn: () => tokenStore.refresh(),
onTokenRefreshed: ({ accessToken }) => tokenStore.setAccess(accessToken),
skipRefreshFor: (ctx) => ctx.url.includes("/auth/")
})
]
});
| Option | Default | Explanation |
|---|---|---|
refreshFn |
None | Function called only once for a wave of concurrent 401 responses. |
onTokenRefreshed |
No hook | Persists the new token before replaying queued requests. |
skipRefreshFor |
No application skip | Excludes login, refresh, logout, health, or public endpoints. |
triggerStatuses |
[401] |
Statuses that trigger Bearer refresh. |
queueTimeoutMs |
30000 |
Maximum wait time during single-flight refresh. |
Refresh loop
refreshFn must not call the same protected client without noAuth, otherwise refresh can trigger refresh again.
Safe Cookie Refresh¶
cookieSafeRefreshGuard({
refreshPath: "/auth/refresh",
excludePaths: ["/auth/login", "/auth/refresh", "/health"]
})
| Option | Default | Explanation |
|---|---|---|
refreshPath |
None | Dedicated endpoint for cookie refresh. |
triggerStatuses |
[401, 419] |
419 often covers expired session or invalid CSRF. |
maxRetry |
1 |
Number of replays of the original request after refresh. |
excludePaths |
[] |
Pathnames ignored by refresh logic. |
honorRetryAfter |
true |
Honors Retry-After or applies cooldown on 429. |
CSRF¶
csrfGuard({
tokenFromCookie: "csrf_token",
tokenFromHeader: "X-CSRF-Token",
headerName: "X-CSRF-Token"
})
| Option | Default | Explanation |
|---|---|---|
tokenFromCookie |
Disabled | Reads a non-HttpOnly browser cookie. |
tokenFromHeader |
Disabled | Remembers the last non-empty response header value. |
headerName |
X-CSRF-Token |
Header injected on mutations. |
applyTo |
POST, PUT, PATCH, DELETE |
Affected methods. |
The backend must expose the CSRF header through CORS if the browser needs to read it.