### Start TanStack Router Example with oidc-spa
Source: https://github.com/keycloakify/docs.oidc-spa.dev/blob/v10/integration-guides/tanstack-router-start/tanstack-start.md
Clones the TanStack Start example from GitHub, installs dependencies, and runs the development server. This command initializes a project configured for oidc-spa.
```bash
npx gitpick keycloakify/oidc-spa/tree/main/examples/tanstack-start start-oidc
cd start-oidc
npm install
npm run dev
# By default, the example runs against Keycloak.
# You can edit the .env file to test other providers.
```
--------------------------------
### Clone and Run Basic Angular oidc-spa Example
Source: https://github.com/keycloakify/docs.oidc-spa.dev/blob/v10/integration-guides/angular.md
Clones the basic oidc-spa Angular example using gitpick, installs dependencies, and starts the development server.
```bash
npx gitpick keycloakify/oidc-spa/tree/main/examples/angular oidc-spa-angular
cd oidc-spa-angular
npm install
npm run start
```
--------------------------------
### Project Setup with npx gitpick
Source: https://github.com/keycloakify/docs.oidc-spa.dev/blob/v10/integration-guides/next.js.md
Initializes a new Next.js project with oidc-spa example code using npx gitpick. This command clones the example repository, sets up the project directory, copies environment variables, installs dependencies, and starts the development server.
```bash
npx gitpick keycloakify/oidc-spa/tree/main/examples/next oidc-spa-next
cd oidc-spa-next
cp .env.local.sample .env.local
npm install
npm run dev
```
--------------------------------
### Setup React Router Framework OIDC Example (Bash)
Source: https://github.com/keycloakify/docs.oidc-spa.dev/blob/v10/integration-guides/react-router.md
This command-line snippet demonstrates how to clone and set up the 'rr-framework-oidc' example project from keycloakify/oidc-spa. It includes steps for installing dependencies, configuring environment variables, and running the development server. The example utilizes preconfigured test accounts for Keycloak, Auth0, or Google OAuth.
```bash
npx gitpick keycloakify/oidc-spa/tree/main/examples/react-router-framework rr-framework-oidc
cd rr-framework-oidc
# You can use our preconfigured Keycloak, Auth0, or Google OAuth test accounts
cp .env.local.sample .env.local
npm install
npm run dev
# Start exploring with: src/oidc.ts
```
--------------------------------
### Clone and Run Advanced Angular oidc-spa Example
Source: https://github.com/keycloakify/docs.oidc-spa.dev/blob/v10/integration-guides/angular.md
Clones the advanced oidc-spa Angular kitchensink example using gitpick, installs dependencies, and starts the development server. This example demonstrates features like token validation and role-based access control.
```bash
npx gitpick keycloakify/oidc-spa/tree/main/examples/angular-kitchensink oidc-spa-angular-kitchensink
cd oidc-spa-angular-kitchensink
npm install
npm run start
```
--------------------------------
### Clone and Run TanStack Router Example with oidc-spa
Source: https://github.com/keycloakify/docs.oidc-spa.dev/blob/v10/integration-guides/tanstack-router-start/react-router.md
This command sequence clones a TanStack Router example project that is preconfigured with oidc-spa. It then navigates into the project directory, copies environment variables, installs dependencies, and starts the development server.
```bash
npx gitpick keycloakify/oidc-spa/tree/main/examples/tanstack-router-file-router tr-oidc
cd tr-oidc
# You can use our preconfigured Keycloak, Auth0, or Google OAuth test accounts
cp .env.local.sample .env.local
npm install
npm run dev
# Start exploring with: src/oidc.ts
```
--------------------------------
### Clone and Run React Router Declarative Example
Source: https://github.com/keycloakify/docs.oidc-spa.dev/blob/v10/integration-guides/react-router.md
This command clones a React Router declarative mode example using `gitpick`. It guides you through setting up environment variables, installing dependencies, and running the development server, starting exploration from `src/oidc.ts`.
```bash
npx gitpick keycloakify/oidc-spa/tree/main/examples/react-router-declarative rr-declarative-oidc
cd rr-declarative-oidc
# You can use our preconfigured Keycloak, Auth0, or Google OAuth test accounts
cp .env.local.sample .env.local
npm install
npm run dev
# Start exploring with: src/oidc.ts
```
--------------------------------
### Test oidc-spa Google Integration
Source: https://github.com/keycloakify/docs.oidc-spa.dev/blob/v10/providers-configuration/google-oauth.md
This bash script demonstrates how to set up and run a project to test the oidc-spa integration with Google OAuth. It involves cloning an example project, configuring environment variables, installing dependencies, and starting the development server.
```bash
npx degit https://github.com/keycloakify/oidc-spa/examples/tanstack-router-file-based oidc-spa-tanstack-router
cd oidc-spa-tanstack-router
cp .env.local.sample .env.local
# Edit .env.local, uncomment the Google section and comment the Keycloak section
# replace the values by your own.
yarn
yarn dev
```
--------------------------------
### Clone and Run React Router Data Mode Example
Source: https://github.com/keycloakify/docs.oidc-spa.dev/blob/v10/integration-guides/react-router.md
This command clones a React Router data mode example using `gitpick`. It provides instructions for setting up environment variables, installing dependencies, and starting the development server, with guidance to begin exploring in `src/oidc.ts`.
```bash
npx gitpick keycloakify/oidc-spa/tree/main/examples/react-router-data rr-data-oidc
cd rr-data-oidc
# You can use our preconfigured Keycloak, Auth0, or Google OAuth test accounts
cp .env.local.sample .env.local
npm install
npm run dev
# Start exploring with: src/oidc.ts
```
--------------------------------
### Install oidc-spa and zod in Angular (bun)
Source: https://github.com/keycloakify/docs.oidc-spa.dev/blob/v10/integration-guides/angular.md
Installs the oidc-spa and zod libraries using bun. Zod is optional but recommended for input validation.
```bash
bun add oidc-spa zod
```
--------------------------------
### Manual Setup for Security Features (Easy)
Source: https://github.com/keycloakify/docs.oidc-spa.dev/blob/v10/resources/migrating-from-keycloak-js.md
This is a simplified manual setup for projects not using Vite and where modifying the entry file is not feasible. It involves calling `oidcEarlyInit` within the same module as the `Keycloak` initialization. Note that this approach offers a reduced security posture compared to the other methods and might conflict with certain routing libraries. It requires importing modules from 'oidc-spa/entrypoint', 'oidc-spa/browser-runtime-freeze', and 'oidc-spa/DPoP'.
```typescript
import { Keycloak } from "oidc-spa/keycloak-js";
import { oidcEarlyInit } from "oidc-spa/entrypoint";
import { browserRuntimeFreeze } from 'oidc-spa/browser-runtime-freeze';
import { DPoP } from 'oidc-spa/DPoP';
// Should run as early as possible.
oidcEarlyInit({
BASE_URL: "/" // The path where your app is hosted
// If applicable you should use `process.env.PUBLIC_URL`
// or `import.meta.env.BASE_URL`.
// This is not an option. There's only one good answer.
securityDefenses: {
// See: https://docs.oidc-spa.dev/v/v10/security-features/browser-runtime-freeze
...browserRuntimeFreeze({
//excludes: [ "fetch", "XMLHttpRequest" ]
}),
// See: https://docs.oidc-spa.dev/v/v10/security-features/dpop
...DPoP({ mode: 'auto' })
}
});
const keycloak = new Keycloak({ /* ... */ });
```
--------------------------------
### Initialize oidc-spa project with Nuxt
Source: https://github.com/keycloakify/docs.oidc-spa.dev/blob/v10/integration-guides/nuxt.md
Commands to scaffold a new Nuxt SPA project using the oidc-spa example template and install necessary dependencies.
```bash
npx gitpick keycloakify/oidc-spa/tree/main/examples/nuxt-spa oidc-spa-nuxt-spa
cd oidc-spa-nuxt-spa
cp .env.local.sample .env.local
yarn install
yarn dev
```
--------------------------------
### Install oidc-spa dependencies
Source: https://context7.com/keycloakify/docs.oidc-spa.dev/llms.txt
Command to install the oidc-spa library and the required zod dependency for schema validation.
```bash
npm install oidc-spa zod
```
--------------------------------
### Install oidc-spa and zod in Angular (npm)
Source: https://github.com/keycloakify/docs.oidc-spa.dev/blob/v10/integration-guides/angular.md
Installs the oidc-spa and zod libraries using npm. Zod is optional but recommended for input validation.
```bash
npm install oidc-spa zod
```
--------------------------------
### Display OIDC Initialization Errors in TanStack Start
Source: https://github.com/keycloakify/docs.oidc-spa.dev/blob/v10/features/error-management/error-handling-with-autologin.md
This example demonstrates integrating OIDC error handling within a TanStack Start application. It utilizes the `useOidc` hook to access `oidcInitializationError` and conditionally renders an `OidcErrorComponent` to inform the user about authentication issues.
```tsx
import { HeadContent, Scripts, createRootRoute } from "@tanstack/react-router";
import Header from "@/components/Header";
import { AutoLogoutWarningOverlay } from "@/components/AutoLogoutWarningOverlay";
import { useOidc } from "@/oidc";
import type { OidcInitializationError } from "oidc-spa/core";
export const Route = createRootRoute({
// ...
shellComponent: RootDocument
});
function RootDocument({ children }: { children: React.ReactNode }) {
const { oidcInitializationError } = useOidc();
return (
{oidcInitializationError ? (
) : (
children
)}
);
}
function OidcErrorComponent(props: {
oidcInitializationError: OidcInitializationError;
}){
const { oidcInitializationError } = props;
// Distinguish misconfiguration vs. temporary auth-server outage.
console.log(oidcInitializationError.isAuthServerLikelyDown);
// Developer-only diagnostic with likely cause and fix.
// Do not display this to end users.
console.log(oidcInitializationError.message);
return
Our auth is down, sorry
;
}
```
--------------------------------
### Install oidc-spa and zod with npm, yarn, pnpm, or bun
Source: https://github.com/keycloakify/docs.oidc-spa.dev/blob/v10/integration-guides/tanstack-router-start/react-router.md
These commands show how to install the 'oidc-spa' and 'zod' packages using different package managers. 'zod' is optional but recommended for data validation.
```bash
npm install oidc-spa zod
```
```bash
yarn add oidc-spa zod
```
```bash
pnpm add oidc-spa zod
```
```bash
bun add oidc-spa zod
```
--------------------------------
### Install oidc-spa and zod in Angular (pnpm)
Source: https://github.com/keycloakify/docs.oidc-spa.dev/blob/v10/integration-guides/angular.md
Installs the oidc-spa and zod libraries using pnpm. Zod is optional but recommended for input validation.
```bash
pnpm add oidc-spa zod
```
--------------------------------
### Deno.serve API Handler with Authentication (TypeScript)
Source: https://github.com/keycloakify/docs.oidc-spa.dev/blob/v10/integration-guides/backend-token-validation/deno.serve.md
This snippet demonstrates a Deno.serve API handler in TypeScript. It sets up authentication using bootstrapAuth, retrieves user details with getUser, and handles GET requests for '/api/todos' and '/api/todos/:userId'. It includes error handling for invalid requests and unauthorized access.
```typescript
import { bootstrapAuth, getUser } from "./auth.ts"; // See below
bootstrapAuth({
implementation: "real", // or "mock", see: https://docs.oidc-spa.dev/v/v8/integration-guides/backend-token-validation/mock-modes
issuerUri: Deno.env.get("OIDC_ISSUER_URI")!,
expectedAudience: Deno.env.get("OIDC_AUDIENCE") ?? undefined
});
Deno.serve(async (request: Request) => {
const url = new URL(request.url);
if (request.method === "GET" && url.pathname === "/api/todos") {
const user = await getUser({ req: request });
// We got an exception, validation failed
if (user instanceof Response) {
const response = user;
return response;
}
const json = await Deno.readTextFile(
`todos_${user.id}.json`
);
return new Response(json, {
status: 200,
headers: { "content-type": "application/json" }
});
}
/**
* Support staff endpoint.
* Example: GET /api/todos/1234
*/
if (request.method === "GET" && url.pathname.startsWith("/api/todos/")) {
let userId: string;
try {
userId = decodeURIComponent(url.pathname.replace("/api/todos/", ""));
} catch {
return new Response("bad request", { status: 400 });
}
if (!userId || userId.includes("/")) {
return new Response("bad request", { status: 400 });
}
{
// Will reject the request if user making the request
// doesn't have "support-staff" role
const user = await getUser({ req: request, requiredRole: "support-staff" });
// We got an exception, validation failed
if (user instanceof Response) {
const response = user;
return response;
}
}
const json = await Deno.readTextFile(`todos_${userId}.json`);
return new Response(json, {
status: 200,
headers: { "content-type": "application/json" }
});
}
return new Response("not found", { status: 404 });
});
```
--------------------------------
### Simplifying OIDC Ready Checks in TanStack Start Components
Source: https://github.com/keycloakify/docs.oidc-spa.dev/blob/v10/features/non-blocking-rendering.md
This code demonstrates how to simplify checks for OIDC readiness within TanStack Start components using the `assert: "ready"` option. This approach removes the need for explicit `isOidcReady` checks, making the code cleaner and more declarative by ensuring the hook only returns values when OIDC is ready.
```tsx
function AuthButtons(props: { className?: string }) {
const { className } = props;
const { isUserLoggedIn } = useOidc({ assert: "ready" });
return (
{isUserLoggedIn ? : }
);
}
function Greeting() {
const { isUserLoggedIn, decodedIdToken } = useOidc({ assert: "ready" });
return (
{isUserLoggedIn ? `Welcome back ${decodedIdToken.name}` : `Hello anonymous visitor!`}
);
}
```
--------------------------------
### Install oidc-spa and zod in Angular (yarn)
Source: https://github.com/keycloakify/docs.oidc-spa.dev/blob/v10/integration-guides/angular.md
Installs the oidc-spa and zod libraries using yarn. Zod is optional but recommended for input validation.
```bash
yarn add oidc-spa zod
```
--------------------------------
### Install oidc-spa dependencies
Source: https://github.com/keycloakify/docs.oidc-spa.dev/blob/v10/integration-guides/nuxt.md
Installation commands for oidc-spa and Zod validation library across different package managers.
```npm
npm install oidc-spa zod
```
```yarn
yarn add oidc-spa zod
```
```pnpm
pnpm add oidc-spa zod
```
```bun
bun add oidc-spa zod
```
--------------------------------
### Hono API Handler Setup with OIDC SPA Authentication
Source: https://github.com/keycloakify/docs.oidc-spa.dev/blob/v10/integration-guides/backend-token-validation/hono.md
This snippet shows a typical Hono API handler setup. It initializes the OIDC SPA authentication module with configuration, defines routes for fetching todos, and demonstrates how to retrieve user information using `getUser` which includes role validation.
```typescript
import { Hono } from "hono";
import * as fs from "node:fs/promises";
import { bootstrapAuth, getUser } from "./auth"; // See below
function startHonoServer() {
bootstrapAuth({
implementation: "real", // or "mock", see: https://docs.oidc-spa.dev/v/v8/integration-guides/backend-token-validation/mock-modes
issuerUri: process.env.OIDC_ISSUER_URI!,
expectedAudience: process.env.OIDC_AUDIENCE
});
const app = new Hono();
app.get("/api/todos", async c => {
const user = await getUser({ req: c.req });
const json = await fs.readFile(`todos_${user.id}.json`, "utf8");
return c.text(json);
});
app.get("/api/todos-for-support/:userId", async c => {
// Will reject the request if user making the request
// doesn't have "support-staff" role
await getUser({ req: c.req, requiredRole: "support-staff" });
const userId = c.req.param("userId");
const json = await fs.readFile(`todos_${userId}.json`, "utf8");
return c.text(json);
});
// ...
}
```
--------------------------------
### Integrate OIDC with React
Source: https://context7.com/keycloakify/docs.oidc-spa.dev/llms.txt
Demonstrates setting up OIDC in a React application using bootstrapOidc and the useOidc hook. It includes examples for protected components and accessing user information.
```typescript
import { oidcSpa } from "oidc-spa/react-spa";
import { z } from "zod";
export const { bootstrapOidc, useOidc, withLoginEnforced } = oidcSpa
.withExpectedDecodedIdTokenShape({
decodedIdTokenSchema: z.object({
sub: z.string(),
preferred_username: z.string(),
email: z.string().optional()
})
})
.createUtils();
bootstrapOidc({
issuerUri: import.meta.env.VITE_OIDC_ISSUER,
clientId: import.meta.env.VITE_OIDC_CLIENT_ID,
debugLogs: true
});
function UserProfile() {
const { isUserLoggedIn, login, logout } = useOidc();
if (!isUserLoggedIn) return ;
const { getDecodedIdToken } = useOidc({ assert: "user logged in" });
return
Welcome, {getDecodedIdToken().preferred_username}
;
}
```
--------------------------------
### Initialize oidc-spa with Keycloak Credentials
Source: https://github.com/keycloakify/docs.oidc-spa.dev/blob/v10/providers-configuration/keycloak.md
Demonstrates how to initialize the oidc-spa library with Keycloak's issuerUri and clientId. This snippet is framework-agnostic and shows the basic setup required for authentication.
```typescript
createOidc({
issuerUri: "https://auth.my-company.com/realms/myeralm",
clientId! "myclient",
// ...
});
```
--------------------------------
### Manual Setup for Security Features (Recommended)
Source: https://github.com/keycloakify/docs.oidc-spa.dev/blob/v10/resources/migrating-from-keycloak-js.md
This configuration is for non-Vite projects or when more control is needed. It involves renaming the main entry point and creating a new one to call `oidcEarlyInit`. This method ensures security features are initialized early in the application lifecycle. It requires importing modules from 'oidc-spa/entrypoint', 'oidc-spa/browser-runtime-freeze', and 'oidc-spa/DPoP'.
```typescript
import { oidcEarlyInit } from "oidc-spa/entrypoint";
import { browserRuntimeFreeze } from 'oidc-spa/browser-runtime-freeze';
import { DPoP } from 'oidc-spa/DPoP';
const { shouldLoadApp } = oidcEarlyInit({
BASE_URL: "/" // The path where your app is hosted
// If applicable you should use `process.env.PUBLIC_URL`
// or `import.meta.env.BASE_URL`.
// This is not an option. There's only one good answer.
securityDefenses: {
// See: https://docs.oidc-spa.dev/v/v10/security-features/browser-runtime-freeze
...browserRuntimeFreeze({
//excludes: [ "fetch", "XMLHttpRequest" ]
}),
// See: https://docs.oidc-spa.dev/v/v10/security-features/dpop
...DPoP({ mode: 'auto' })
}
});
if( shouldLoadApp ){
import("./main.lazy");
}
```
--------------------------------
### Configure oidc-spa with Parameters (Framework Agnostic, TypeScript)
Source: https://github.com/keycloakify/docs.oidc-spa.dev/blob/v10/providers-configuration/auth0.md
Demonstrates how to initialize oidc-spa using the `createOidc` function with essential parameters like `issuerUri`, `clientId`, and `extraQueryParams`. It also highlights the optional `idleSessionLifetimeInSeconds` for auto-logout synchronization.
```typescript
createOidc({
issuerUri: "auth.my-company.com",
clientId: "DzXSmwQS7oSTQGLbafhrPXYLT0mOMyZD"
extraQueryParams: {
audience: "https://app.my-company.com/api"
}
// (Optional) This must be kept in sync with the Idle Session Lifetime value
// configured in the Auth0 dashboard. To ensure correct autoLogout behavior.
idleSessionLifetimeInSeconds: 1800,
// ...
});
```
--------------------------------
### Manual oidc-spa Initialization (Recommended)
Source: https://github.com/keycloakify/docs.oidc-spa.dev/blob/v10/integration-guides/react-router.md
This method is recommended for non-Vite projects with a single client entry point. It involves renaming the main entry file and creating a new one to call `oidcEarlyInit` before deferring the main app import, optimizing authentication speed.
```bash
mv src/main.ts src/main.lazy.ts
```
```typescript
import { oidcEarlyInit } from "oidc-spa/entrypoint";
const { shouldLoadApp } = oidcEarlyInit({
BASE_URL: "/" // The path where your app is hosted. You can also pass it later to createOidc().
});
if (shouldLoadApp) {
// Note: Deferring the main app import adds a few milliseconds to cold start,
// but dramatically speeds up auth. Overall, it's a net win.
import("./main.lazy");
}
```
--------------------------------
### Fastify Server Setup with OIDC SPA Authentication
Source: https://github.com/keycloakify/docs.oidc-spa.dev/blob/v10/integration-guides/backend-token-validation/fastify.md
This snippet demonstrates setting up a Fastify server, bootstrapping OIDC SPA authentication, and defining API endpoints that require user authentication. It includes reading user-specific data and handling requests with role-based access control.
```typescript
import Fastify from "fastify";
import * as fs from "node:fs/promises";
import { bootstrapAuth, getUser } from "./auth"; // See below
async function startFastifyServer() {
bootstrapAuth({
implementation: "real", // or "mock", see: https://docs.oidc-spa.dev/v/v8/integration-guides/backend-token-validation/mock-modes
issuerUri: process.env.OIDC_ISSUER_URI!,
expectedAudience: process.env.OIDC_AUDIENCE
});
const fastify = Fastify({
// If you run behind a reverse proxy, you almost always want this enabled.
// It affects things like the computed request origin.
trustProxy: true
});
fastify.get("/api/todos", async (req, reply) => {
const user = await getUser({ req, reply });
const json = await fs.readFile(
`todos_${user.id}.json`,
"utf8"
);
reply.code(200).type("application/json").send(json);
});
fastify.get("/api/todos-for-support/:userId", async (req, reply) => {
// Will reject the request if user making the request
// doesn't have "support-staff" role
await getUser({ req, reply, requiredRole: "support-staff" });
const { userId } = req.params as { userId: string };
const json = await fs.readFile(
`todos_${userId}.json`,
"utf8"
);
reply.code(200).type("application/json").send(json);
});
// ...
await fastify.listen({
port: parseInt(process.env.PORT ?? "3000"),
host: "0.0.0.0"
});
}
```
--------------------------------
### Rename Angular Entrypoint
Source: https://github.com/keycloakify/docs.oidc-spa.dev/blob/v10/integration-guides/angular.md
Renames the main TypeScript entry point file from `main.tsx` to `main.lazy.tsx` as part of the oidc-spa setup.
```bash
mv src/main.tsx src/main.lazy.tsx
```
--------------------------------
### Authentication Utilities for Server-Side (TypeScript)
Source: https://github.com/keycloakify/docs.oidc-spa.dev/blob/v10/integration-guides/backend-token-validation/deno.serve.md
This snippet defines utility functions for server-side authentication using the 'oidc-spa' library. It includes 'bootstrapAuth' for initializing the authentication process and 'getUser' for validating access tokens and extracting user information, with support for role-based authorization.
```typescript
import { oidcSpa, extractRequestAuthContext } from "npm:oidc-spa@latest/server";
import { z } from "npm:zod@latest";
const { bootstrapAuth, validateAndDecodeAccessToken } = oidcSpa
.withExpectedDecodedAccessTokenShape({
// This is purely declarative. Here you'll specify
// the claim that you expect to be present in the access token payload.
decodedAccessTokenSchema: z.object({
sub: z.string(),
name: z.string(),
email: z.string().optional(),
// Keycloak specific, convention to manage authorization.
realm_access: z.object({
roles: z.array(z.string())
}).optional()
})
})
.createUtils();
export { bootstrapAuth };
// Your local representation of a user.
export type User = {
id: string;
name: string;
email: string | undefined;
};
export async function getUser(params: {
req: Request;
requiredRole?: "realm-admin" | "support-staff";
}): Promise {
const { req, requiredRole } = params;
const requestAuthContext = extractRequestAuthContext({
request: req,
// Set this to false only if you don't have a reverse HTTP proxy in front of your
// server. (Almost never the case in modern deployments).
trustProxy: true
});
if (!requestAuthContext) {
// Demo shortcut: we return 401 on missing Authorization, but a mixed
// public/private endpoint could instead return undefined here and let
// the caller decide whether to process an anonymous request.
console.warn("Anonymous request");
return new Response("unauthorized", { status: 401 });
}
if (!requestAuthContext.isWellFormed) {
console.warn(requestAuthContext.debugErrorMessage);
return new Response("bad request", { status: 400 });
}
const { isSuccess, debugErrorMessage, decodedAccessToken } =
await validateAndDecodeAccessToken(
requestAuthContext.accessTokenAndMetadata
);
if (!isSuccess) {
console.warn(debugErrorMessage);
return new Response("unauthorized", { status: 401 });
}
// Your custom Authorization logic: Grant per request access depending
// on the access token claim.
// ... (rest of the implementation)
return { id: decodedAccessToken.sub, name: decodedAccessToken.name, email: decodedAccessToken.email };
}
```
--------------------------------
### TanStack Start Auto Login Integration
Source: https://github.com/keycloakify/docs.oidc-spa.dev/blob/v10/features/auto-login.md
Integrate Auto Login into your TanStack Start application by adding the `.withAutoLogin()` configuration. This simplifies authentication logic by removing the need for explicit login enforcement and session checks.
```diff
import { oidcSpa } from "oidc-spa/react-tanstack-start";
export const {
bootstrapOidc,
useOidc,
getOidc,
oidcFnMiddleware,
oidcRequestMiddleware,
- enforceLogin
} = oidcSpa
.withExpectedDecodedIdTokenShape({ /* ... */ })
.withAccessTokenValidation({ /* ... */ })
+ .withAutoLogin()
.createUtils();
```
```tsx
import { HeadContent, Scripts, createRootRoute } from "@tanstack/react-router";
import Header from "@/components/Header";
import { AutoLogoutWarningOverlay } from "@/components/AutoLogoutWarningOverlay";
import { useOidc } from "@/oidc";
export const Route = createRootRoute({
// ...
shellComponent: ShellComponent,
// NOTE: Even with SSR disabled here, the ShellComponent is still SSR'd.
// Only page components lose SSR.
// You *can* disable SSR per-page for routes that don't load authed data,
// but if your app isn’t public, it’s simpler to SSR only the shell.
ssr: false
});
function ShellComponent({ children }: { children: React.ReactNode }) {
const { isOidcReady } = useOidc();
return (
<html lang="en">
<head>
<HeadContent />
</head>
<body>
<div className="min-h-screen flex flex-col">
<Header />
<main className="flex flex-1 flex-col">
{isOidcReady &&
children
}
</main>
</div>
<AutoLogoutWarningOverlay />
<Scripts />
</body>
</html>
);
}
```
```diff
import { useOidc } from "@/oidc";
-function AuthButtons() {
- const { hasInitCompleted, isUserLoggedIn } = useOidc();
-
- if (!hasInitCompleted) {
- return null;
- }
-
- return isUserLoggedIn ? : ;
-}
-
-function LoggedInAuthButton() {
- const { logout } = useOidc({ assert: "user logged in" });
-
- return (
-
- );
-}
-
-function NotLoggedInAuthButton() {
- const { login, issuerUri } = useOidc({ assert: "user not logged in" });
-
- return (
-
-
-
- );
-}
+function AuthButtons() {
+
+ const { isOidcReady, logout } = useOidc();
+
+ if (!isOidcReady) {
+ return null;
+ }
+
+ return (
+
+ );
+}
```
```diff
-oidcFnMiddleware({ assert: "user logged in" })
+oidcFnMiddleware()
-oidcRequestMiddleware({ assert: "user logged in" })
+oidcRequestMiddleware()
```
```diff
export const Route = createFileRoute("/demo/start/api-request")({
```
--------------------------------
### Manual oidc-spa Initialization for App Entrypoint
Source: https://github.com/keycloakify/docs.oidc-spa.dev/blob/v10/integration-guides/tanstack-router-start/react-router.md
This code shows the 'Manual - Recommended' approach for initializing oidc-spa. It involves renaming the original entry point (e.g., main.ts to main.lazy.ts) and creating a new main.ts that calls 'oidcEarlyInit' and conditionally imports the lazy-loaded application.
```typescript
import { oidcEarlyInit } from "oidc-spa/entrypoint";
const { shouldLoadApp } = oidcEarlyInit({
BASE_URL: "/" // The path where your app is hosted. You can also pass it later to createOidc().
});
if (shouldLoadApp) {
// Note: Deferring the main app import adds a few milliseconds to cold start,
// but dramatically speeds up auth. Overall, it's a net win.
import("./main.lazy");
}
```
--------------------------------
### Configure DPoP (Demonstrating Proof-of-Possession)
Source: https://context7.com/keycloakify/docs.oidc-spa.dev/llms.txt
Shows how to enable DPoP to bind access tokens to cryptographic keys, preventing token replay attacks. Configuration is supported via Vite plugins or manual initialization in the application entry point.
```typescript
// vite.config.ts - Vite Plugin approach
import { defineConfig } from "vite";
import { oidcSpa } from "oidc-spa/vite-plugin";
export default defineConfig({
plugins: [
oidcSpa({
browserRuntimeFreeze: { enabled: true },
DPoP: { enabled: true, mode: "auto" } // "auto" or "enforced"
})
]
});
// Manual approach - src/main.ts
import { oidcEarlyInit } from "oidc-spa/entrypoint";
import { browserRuntimeFreeze } from "oidc-spa/browser-runtime-freeze";
import { DPoP } from "oidc-spa/DPoP";
const { shouldLoadApp } = oidcEarlyInit({
BASE_URL: "/",
securityDefenses: {
...browserRuntimeFreeze(),
...DPoP({ mode: "auto" })
}
});
if (shouldLoadApp) {
import("./main.lazy");
}
// Usage remains unchanged - DPoP is transparent
const { accessToken } = await oidc.getTokens();
fetch("/api/data", { headers: { Authorization: `Bearer ${accessToken}` } });
```
--------------------------------
### Example Access Token Claims
Source: https://github.com/keycloakify/docs.oidc-spa.dev/blob/v10/features/talking-to-multiple-apis-with-different-access-tokens.md
Shows an example of claims found within an access token, highlighting the 'aud' (audience) field which specifies the intended resource server. Different APIs may require different claims.
```json
{
"aud": "https://api1.example.com",
"sub": "xxxxxx",
"groups": ["staff"]
}
```
--------------------------------
### CSP Configuration Example for Session Restoration
Source: https://github.com/keycloakify/docs.oidc-spa.dev/blob/v10/resources/csp-configuration.md
This example demonstrates the necessary Content-Security-Policy directives to allow oidc-spa to perform silent session restoration using iframes. It specifically focuses on relaxing frame-src to include the IdP domain and frame-ancestors to allow the application to be framed by itself.
```nginx
Content-Security-Policy:
frame-src https://auth.my-domain.com;
frame-ancestors 'self';
...other CSP directives...
```
--------------------------------
### Manual oidc-spa Initialization in src/oidc.ts
Source: https://github.com/keycloakify/docs.oidc-spa.dev/blob/v10/integration-guides/tanstack-router-start/react-router.md
This snippet illustrates the 'Manual - Easy' approach for oidc-spa initialization, suitable for projects not using Vite or when the entry file cannot be edited. It involves calling 'oidcEarlyInit' early in 'src/oidc.ts'. This method may have security implications and potential conflicts with client-side routing.
```typescript
import { oidcEarlyInit, } from "oidc-spa/entrypoint";
import { oidcSpa } from "oidc-spa/react-spa";
// Should run as early as possible.
oidcEarlyInit({
BASE_URL: "/" // The path where your app is hosted
});
export const { /* ... */ } = oidcSpa./*...*/
```
--------------------------------
### GET /api/admin/users
Source: https://context7.com/keycloakify/docs.oidc-spa.dev/llms.txt
Retrieves the list of users. Restricted to users with the 'realm-admin' role.
```APIDOC
## GET /api/admin/users
### Description
Admin-only endpoint to retrieve user data. Validates both the token and the required 'realm-admin' role.
### Method
GET
### Endpoint
/api/admin/users
### Parameters
None
### Request Example
GET /api/admin/users
Authorization: Bearer
### Response
#### Success Response (200)
- **users** (array) - List of system users
#### Response Example
{
"users": []
}
#### Error Response (403)
Returned if the user does not possess the 'realm-admin' role.
```
--------------------------------
### Conditional Rendering with TanStack Start and OIDC Initialization
Source: https://github.com/keycloakify/docs.oidc-spa.dev/blob/v10/features/non-blocking-rendering.md
This snippet demonstrates how to conditionally render parts of a React application based on OIDC readiness in TanStack Start. It ensures that UI components dependent on OIDC are only displayed after the initialization process is complete, preventing layout shifts and ensuring a smooth user experience.
```tsx
import { HeadContent, Scripts, createRootRoute } from "@tanstack/react-router";
import Header from "@/components/Header";
import { AutoLogoutWarningOverlay } from "@/components/AutoLogoutWarningOverlay";
import appCss from "../styles.css?url";
import { useOidc } from "@/oidc";
export const Route = createRootRoute({
head: () => ({ /* ... */ }),
shellComponent: RootDocument
});
function RootDocument({ children }: { children: React.ReactNode }) {
const { isOidcReady } = useOidc();
return (
{isOidcReady && (
<>
{children}
>
)}
);
}
```
--------------------------------
### Handle OIDC Initialization Errors in Angular
Source: https://github.com/keycloakify/docs.oidc-spa.dev/blob/v10/features/error-management/error-handling-with-autologin.md
This example shows how to check for and handle OIDC initialization errors within an Angular application. It logs diagnostic information, similar to the React example, distinguishing between server outages and configuration issues. The code utilizes Angular's dependency injection to access the OIDC service.
```html
@if (oidc.initializationError) {
Our Auth is down, sorry :(
}@else{
}
```
```typescript
@Component({
selector: 'app-root',
imports: [RouterOutlet, RouterLink, RouterLinkActive],
templateUrl: './app.html',
})
export class App {
oidc = inject(Oidc);
constructor(){
if( this.oidc.initializationError ){
const { initializationError } = this.oidc;
// Distinguish a misconfiguration from a temporary auth-server outage.
console.log(initializationError.isAuthServerLikelyDown);
// Developer-only diagnostic with likely cause and fix.
// Do not display this to end users.
console.log(initializationError.message);
}
}
}
```
--------------------------------
### Hono Server with WebSockets (TypeScript)
Source: https://github.com/keycloakify/docs.oidc-spa.dev/blob/v10/integration-guides/backend-token-validation/websocket.md
Sets up a Hono server with WebSocket functionality using `@hono/node-ws`. It bootstraps authentication, defines API endpoints, and handles WebSocket upgrades, extracting user information from the 'Sec-WebSocket-Protocol' header.
```typescript
import { Hono } from "hono";
import { createNodeWebSocket } from "@hono/node-ws";
import { serve } from "@hono/node-server";
import { bootstrapAuth, getUser, getUser_ws } from "./auth"; // See below
function startHonoServer() {
bootstrapAuth({
implementation: "real", // or "mock", see: https://docs.oidc-spa.dev/v/v8/integration-guides/backend-token-validation/mock-modes
issuerUri: process.env.OIDC_ISSUER_URI!,
expectedAudience: process.env.OIDC_AUDIENCE
});
const app = new Hono();
app.get("/api/todos", async c => { /* ... */ });
const { injectWebSocket, upgradeWebSocket } = createNodeWebSocket({ app });
app.get(
"/ws",
upgradeWebSocket(async c => {
const user = await getUser_ws({ req: c.req });
return {
onOpen: (_event, ws) => {
ws.send(`Hello ${user.name}`);
},
onMessage(event, ws) {
ws.send(`I'm not very smart, all I can do is repeat: "${event.data}"`);
}
};
})
);
const server = serve({
fetch: app.fetch,
port
});
injectWebSocket(server);
}
```