pasbydocs
OIDC API

React & Node integration

@finsel-dgi/pasby-react — loginWithSecret, tokenSwap, and eidResource for custom backends.

@finsel-dgi/pasby-react provides server-side helpers for the OIDC API. Use it with Express, Fastify, Remix loaders, or any Node HTTP stack. For Next.js App Router, prefer @finsel-dgi/pasby-next which builds on this package.

npm: @finsel-dgi/pasby-react · Repository: github.com/Finsel-DGI/pasby-auth-react


Install

npm install @finsel-dgi/pasby-react

Server functions import from the /server subpath (never bundle secrets to the browser):

import {
  loginWithSecret,
  tokenSwap,
  eidResource,
} from "@finsel-dgi/pasby-react/server";

Environment variables

VariablePurpose
PASBY_CONSUMER_KEYx-api-key on session start
PASBY_CLIENT_SECRETx-access-secret on session start
PASBY_CLIENT_IDApp id on resource call
SECRET_GENEncrypt/decrypt PKCE verifier and tokens in cookies

Server exports

ExportOIDC stepMaps to
loginWithSecretStart sessionPOST /oidc/kipindi
tokenSwapExchange tokenPOST /oidc/kupeana
eidResourceGet claimsPOST /oidc/resource
getUserDecode access cookieJWT sub only (no resource call)

Types: User from @finsel-dgi/pasby-react.


Express example

Start login

import express from "express";
import { loginWithSecret } from "@finsel-dgi/pasby-react/server";

const app = express();

app.get("/auth/login", async (req, res) => {
  const { redirect, pkceverifier, id } = await loginWithSecret({
    claims: ["naming.given", "naming.family", "contact.email"],
    action: "login",
    payload: "Sign in to your app",
    redirect_uri: "https://your-app.com/auth/callback",
  });

  res.cookie("pasby_pkce", pkceverifier, {
    httpOnly: true,
    secure: true,
    sameSite: "lax",
    maxAge: 10 * 60 * 1000,
  });

  res.redirect(redirect);
});

loginWithSecret generates PKCE, calls start session, and returns:

FieldUse
redirectHosted identification URL — redirect the browser here
pkceverifierEncrypted verifier — store in httpOnly cookie until callback
idSession id for support correlation

Callback — exchange + resource

app.get("/auth/callback", async (req, res) => {
  const { handshake, flow } = req.query as Record<string, string>;
  const pkceverifier = req.cookies.pasby_pkce;

  if (flow === "cancelled") {
    return res.redirect("/auth/cancelled");
  }

  const tokens = await tokenSwap({
    flow,
    code: handshake,
    pkceverifier,
  });

  const user = await eidResource({
    accessCode: tokens.access,
    challenge: tokens.challenge,
  });

  // Create your app session from user.national / user.claims
  req.session.userId = user.national;
  res.redirect("/dashboard");
});

tokenSwap returns encrypted access and challenge — pass them straight into eidResource (the SDK decrypts internally).

Optional: poll UI component

For signing flows that need client polling, the package exports PollEIDComponent from the main entry (browser-safe).


User shape

import type { User } from "@finsel-dgi/pasby-react";

const user: User = {
  national: "12345678901",
  country: "NG",
  claims: {
    contact: {
      email: "jane@example.com",
      emailVerified: true,
    },
    naming: {
      given: "Jane",
      family: "Doe",
    },
  },
};

Full claim keys: Claims reference.


PKCE

loginWithSecret generates PKCE via @rebatlabs/ui-funs and encrypts the verifier with SECRET_GEN. You do not call PKCE helpers manually unless you bypass the SDK.

If you implement raw HTTP instead, see PKCE and the Go examples in OIDC quickstart.


On this page