Documentation
Protecting Routes
Keep authorization decisions in your app using local sessions backed by Radiant Auth tokens.
Recommended pattern
- After OAuth callback, create a server-side session row that stores tokens.
- Set an opaque httpOnly cookie referencing that session.
- On protected routes, load the session from the cookie.
- Refresh tokens if the access token is near expiry.
- Redirect unauthenticated users to your login route (which starts OAuth).
require-user.ts
// Pseudocode — adapt to your framework
export async function requireUser(request: Request) {
const sessionId = getCookie(request, "app_session");
if (!sessionId) return Response.redirect("/login", 302);
const session = await db.sessions.find(sessionId);
if (!session) return Response.redirect("/login", 302);
if (session.accessTokenExpiresAt < Date.now() + 60_000) {
await refreshSessionTokens(session);
}
return session.user;
}API routes
For JSON APIs, return 401 instead of redirecting. Optionally accept a Bearer access token for machine clients, verifying JWTs with JWKS when audience-bound tokens are used.
First-party session checks
JWT access tokens cannot be revoked mid-lifetime. First-party Radiant apps should call POST /api/internal/user-access after verifying the token so bans and revoked OAuth grants take effect immediately. Authenticate that call with INTERNAL_API_SECRET.
What not to do
- Do not trust client-supplied user IDs without a verified session/token.
- Do not put access tokens in localStorage for confidential web apps.
- Do not skip
statevalidation on the OAuth callback.
Tip
Pair route guards with logout that both clears the cookie and revokes tokens.