OIDC quickstart
Hosted identification with PKCE — Next.js, React, Node, or Go.
The OIDC flow is four server-side steps: start session → user identifies → exchange token → fetch claims. Use an official SDK when you can; raw HTTP is for other stacks.
| Stack | Package | Guide |
|---|---|---|
| Next.js App Router | @finsel-dgi/pasby-next | Next.js OIDC |
| React + Node backend | @finsel-dgi/pasby-react | React OIDC |
| Go, PHP, Ruby, … | REST | Steps below (Go tab) + API reference |
Prerequisites
- Sandbox API key and app secret from Console
- HTTPS callback URL registered for your app (
https://your-host/auth/callbackor/api/eid/handshakefor Next.js) - PKCE generated server-side (SDKs do this for you)
Set environment variables before running examples:
| Variable | Used by |
|---|---|
PASBY_CONSUMER_KEY | x-api-key on session start |
PASBY_CLIENT_SECRET | x-access-secret on session start |
PASBY_CLIENT_ID | App id on resource call |
SECRET_GEN | Encrypt PKCE verifier and tokens in cookies (React / Next.js) |
1. Start session
Redirect the user to the identification link returned by pasby. Store the PKCE verifier server-side until exchange.
// app/api/eid/[auth]/route.ts
import { handler } from "@finsel-dgi/pasby-next/server";
import { NextRequest } from "next/server";
const pasby = handler(
{
claims: ["contact.email", "naming.given", "naming.family"],
action: "login",
payload: "Sign in to your app",
},
"/auth/error",
);
export async function GET(
request: NextRequest,
{ params }: { params: Promise<{ auth: string }> },
) {
return pasby(request, { params: await params });
}The button calls GET /api/eid/login; the handler starts the OIDC session and redirects to pasby. Console callback: https://your-host/api/eid/handshake.
import { loginWithSecret } from "@finsel-dgi/pasby-react/server";
const { redirect, pkceverifier, id } = await loginWithSecret({
claims: ["contact.email", "naming.given", "naming.family"],
action: "login",
payload: "Sign in to your app",
redirect_uri: "https://your-app.com/auth/callback",
});
// Store pkceverifier in an httpOnly cookie or server session, then:
// res.redirect(redirect);Details: Start session · PKCE
2. User identifies
The user completes login on the hosted UI (national.eid.pasby.africa). pasby redirects back to your callback with query parameters — typically handshake (JWT) and flow (session id). If the user cancels, flow=cancelled.
Next.js: handled automatically by the handshake route from handler().
3. Exchange token
Trade the handshake + PKCE verifier for a short-lived Bearer token and a session challenge (required on the next call).
// Handled inside GET /api/eid/handshake by handler().
// Sets httpOnly cookies for access token and session challenge.Details: Exchange token
4. Get claims
Fetch national ID and consented claim groups.
import { getEID } from "@finsel-dgi/pasby-next/server";
import { cookies } from "next/headers";
const user = await getEID(await cookies());
// user.national, user.country, user.claims.contact.email, ...Sandbox apps may return synthetic users; production returns real registered identities.
Details: Get user claims · Claims reference
Next steps
- Next.js OIDC — env vars, multi-tenant
createPasbyHandler, logout - React OIDC — Express-style routes, cookie pattern,
Usertype - Client libraries — package overview
- Errors — handshake expired, wrong PKCE, token TTL