Authentication – fluent-wp-client
0 Stars
View on GitHub
Overview
Section titled “Overview”fluent-wp-client supports static auth and request-aware auth.
export function createWordPressClientForRequest(request: Request): WordPressClient { const token = readUserJwtFromRequest(request); return new WordPressClient({ baseUrl: process.env.WP_BASE_URL!, auth: token ? { token } : undefined, });}Which method should I use?
Section titled “Which method should I use?”| Use case | Best option |
|---|---|
| Public read-only content | No auth |
| Backend jobs, admin scripts | Basic auth (application passwords) |
| SPA/mobile, external token flow | JWT auth |
| Logged-in WordPress browser session | Cookie + nonce |
Prebuilt Authorization value | authHeader or auth.authorization |
| Signature/HMAC/OAuth-like | authHeaders provider |
| Request-scoped auth selection | createAuthResolver |
Static auth
Section titled “Static auth”const wp = new WordPressClient({ baseUrl: 'https://example.com' });const wp = new WordPressClient({ baseUrl: 'https://example.com', auth: { username: 'admin', password: 'app-password' },});const wp = new WordPressClient({ baseUrl: 'https://example.com', auth: { token: 'jwt-token' },});const wp = new WordPressClient({ baseUrl: 'https://example.com', auth: { nonce: window.wpApiSettings.nonce, credentials: 'include' },});const wp = new WordPressClient({ baseUrl: 'https://example.com', authHeader: 'Bearer jwt-token',});Request-aware auth headers
Section titled “Request-aware auth headers”Use authHeaders when auth must be computed per request (signatures, HMAC, rotating keys):
const wp = new WordPressClient({ baseUrl: 'https://example.com', authHeaders: ({ method, url, body }) => ({ Authorization: createSignedAuthHeader({ method, url: url.toString(), body }), }),});Resolver helpers
Section titled “Resolver helpers”createAuthResolver returns a typed function that selects an auth shape based on context. It does not authenticate — it only picks the right credentials.
const resolveAuth = createAuthResolver<RequestContext>((ctx) => { if (ctx.isBrowser && ctx.nonce) return { nonce: ctx.nonce, credentials: 'include' }; if (ctx.token) return { token: ctx.token }; return null;});
const auth = await resolveAuth(context);const post = await wp.request({ endpoint: '/posts/1', auth: auth ?? undefined });Use resolvers when auth depends on who is making the request, where it runs, or how credentials are stored.
Framework examples
Section titled “Framework examples”Express (no resolver needed)
Section titled “Express (no resolver needed)”app.use(async (req, _res, next) => { req.wp = new WordPressClient({ baseUrl: process.env.WP_BASE_URL!, auth: req.user?.wpJwt ? { token: req.user.wpJwt } : undefined, }); next();});Generic SSR handler
Section titled “Generic SSR handler”import { WordPressClient, createAuthResolver, resolveWordPressAuth, type RequestAuthResolver } from 'fluent-wp-client';
const requestAuth: RequestAuthResolver = createAuthResolver((request) => { const jwt = request.headers.get('cookie')?.match(/wp_jwt=([^;]+)/)?.[1]; if (jwt) return { token: decodeURIComponent(jwt) }; if (process.env.WP_APP_PASSWORD) return { username: 'admin', password: process.env.WP_APP_PASSWORD }; return null;});
export async function handleRequest(request: Request) { const auth = await resolveWordPressAuth(requestAuth, request); const wp = new WordPressClient({ baseUrl: 'https://example.com', auth }); return wp.users().me();}Astro Actions
Section titled “Astro Actions”import type { ActionAPIContext } from 'astro:actions';import { createAuthResolver, resolveWordPressAuth } from 'fluent-wp-client';
const actionAuth = createAuthResolver<ActionAPIContext>((ctx) => { const jwt = ctx.cookies.get('wp_jwt')?.value; if (jwt) return { token: jwt }; if (process.env.WP_APP_PASSWORD) return { username: 'admin', password: process.env.WP_APP_PASSWORD }; return null;});Next.js App Router
Section titled “Next.js App Router”import { WordPressClient, createAuthResolver, resolveWordPressAuth } from 'fluent-wp-client';
const nextAuth = createAuthResolver<{ request: Request; params: { slug: string } }>(({ request }) => { const bearer = request.headers.get('authorization'); if (bearer) return bearer; const jwt = request.headers.get('cookie')?.match(/wp_jwt=([^;]+)/)?.[1]; return jwt ? { token: decodeURIComponent(jwt) } : null;});
export async function GET(request: Request, { params }: { params: { slug: string } }) { const auth = await resolveWordPressAuth(nextAuth, { request, params }); const wp = new WordPressClient({ baseUrl: process.env.WORDPRESS_BASE_URL!, auth }); return Response.json(await wp.content('posts').item(params.slug));}HMAC/signature auth
Section titled “HMAC/signature auth”const wp = new WordPressClient({ baseUrl: 'https://example.com', authHeaders: ({ method, url, body }) => ({ Authorization: createSignedAuthHeader({ method, url: url.toString(), body }), 'X-Signature-Timestamp': new Date().toISOString(), }),});Utility helpers
Section titled “Utility helpers”createBasicAuthHeader(credentials)createJwtAuthHeader(credentialsOrToken)createWordPressAuthHeader(authInput)loginWithJwt({ username, password })validateJwtToken(token?)