| Time | Method | Endpoint | App | Status | Latency |
|---|---|---|---|---|---|
Connect your logging middleware to populate live data | |||||
Pass as Authorization: Bearer <token> to the portal API.
Drop-in OIDC for Node.js. PKCE, session management, token rotation, and role gates — production-ready out of the box.
One package covers PKCE, token exchange, session management, and JWKS verification.
npm install @oaauth/sdkyarn add @oaauth/sdkpnpm add @oaauth/sdkGrab your SDK key from the dashboard. Internal credentials are resolved server-side.
SDK_KEY=sdk_live_your_key_here
SDK_GATEWAY_URL=https://auth-q03m.onrender.com
OIDC_REDIRECT_URI=http://localhost:4000/callbacksdk_live_ and sdk_test_ prefixes work. Use test keys during development.
Three config values. OIDC endpoints are discovered automatically from your issuer.
const { AuthClient } = require('@oaauth/sdk');
const auth = new AuthClient({
sdkKey: process.env.SDK_KEY,
gatewayUrl: process.env.SDK_GATEWAY_URL,
redirectUri: process.env.OIDC_REDIRECT_URI,
});
module.exports = auth;import { AuthClient } from '@oaauth/sdk';
export const auth = new AuthClient({
sdkKey: process.env.SDK_KEY!,
gatewayUrl: process.env.SDK_GATEWAY_URL!,
redirectUri: process.env.OIDC_REDIRECT_URI!,
});import { AuthClient } from '@oaauth/sdk';
export const auth = new AuthClient({
sdkKey: Bun.env.SDK_KEY,
gatewayUrl: Bun.env.SDK_GATEWAY_URL,
redirectUri: Bun.env.OIDC_REDIRECT_URI,
});Five routes cover the full OIDC flow — login, callback, session, refresh, and logout.
// GET /login — redirect user to OIDC provider
app.get('/login', auth.login);
// auth.login is a pre-bound Express handler.
// It generates PKCE params, stores state, and redirects.
// GET /callback — exchange code, create session
app.get('/callback', async (req, res) => {
const { accessToken, refreshToken, user }
= await auth.handleCallbackAndCreateSession(req);
res.cookie('refreshToken', refreshToken, {
httpOnly: true, sameSite: 'lax'
});
res.json({ accessToken, user });
});
// Protect a single route — req.user is populated
app.get('/me', auth.protect(), (req, res) => {
res.json(req.user); // { sub, email, name, roles }
});
// Optional auth — req.user is null if no token
app.get('/feed', auth.protect({ optional: true }), handler);
// Protect an entire router
const apiRouter = express.Router();
apiRouter.use(auth.protect());
app.use('/api', apiRouter);
// POST /refresh — pre-built handler
// Reads refreshToken from cookie or body.
// Rotates the token and sets the updated cookie.
app.post('/refresh', auth.refreshRoute());
// Custom cookie name:
app.post('/refresh', auth.refreshRoute({
cookieName: 'rt'
}));
// POST /logout — pre-built handler
// Revokes session, clears cookie.
app.post('/logout', auth.logoutRoute());
// Force-logout all devices for a user:
await auth.revokeAllSessions(req.user.sub);
// requireRole() — compose after protect()
app.delete(
'/admin/users/:id',
auth.protect(),
auth.requireRole('admin'),
deleteUser
);
// Multiple allowed roles:
auth.requireRole(['admin', 'moderator'])
// GET /api/me/sessions — list active sessions
app.get('/api/me/sessions',
auth.protect(),
async (req, res) => {
const sessions = await auth.getSessions(req.user.sub);
res.json({ sessions });
}
);
// POST /api/me/logout-all — revoke every session
app.post('/api/me/logout-all',
auth.protect(),
async (req, res) => {
const result = await auth.revokeAllSessions(req.user.sub);
res.clearCookie('refreshToken');
res.json({ success: true, revoked: result.revoked });
}
);
localVerify: false to always verify via gateway.
A complete Express server using the SDK — every route, proper error handling.
// Install: npm i express cookie-parser @oaauth/sdk dotenv
require('dotenv').config();
const express = require('express');
const cookies = require('cookie-parser');
const { AuthClient } = require('@oaauth/sdk');
const app = express();
const auth = new AuthClient({
sdkKey: process.env.SDK_KEY,
gatewayUrl: process.env.SDK_GATEWAY_URL,
redirectUri: process.env.OIDC_REDIRECT_URI,
});
app.use(express.json());
app.use(cookies());
app.get('/login', auth.login);
app.get('/callback', async (req, res) => {
try {
const result = await auth.handleCallbackAndCreateSession(req);
res.cookie('refreshToken', result.refreshToken,
{ httpOnly: true, sameSite: 'lax' });
res.json({ accessToken: result.accessToken, user: result.user });
} catch(e) { res.status(400).json({ error: e.message }); }
});
app.post('/refresh', auth.refreshRoute());
app.post('/logout', auth.logoutRoute());
app.get('/me', auth.protect(), (req,res) => res.json(req.user));
app.listen(4001);npm i express cookie-parser @oaauth/sdk dotenv
OAauth is an auth infrastructure layer for Node.js applications. It handles the full OIDC flow — PKCE generation, token exchange, session lifecycle, and JWT verification — so your application never touches raw credentials.
localVerify: false.
When a user logs in, your server redirects them to the OIDC provider via auth.login. After the provider authenticates the user, it redirects back to your /callback route. The SDK exchanges the authorization code for tokens, creates an opaque session (stored in the SDK gateway), and returns an access token and refresh token to your application.
Your frontend holds the short-lived access token in memory. The refresh token lives in an httpOnly cookie, invisible to JavaScript. When the access token expires, your frontend calls /refresh and gets a new pair — silently, without the user noticing.
The SDK requires Node.js 18 or later.
# Choose your package manager
npm install @oaauth/sdk
yarn add @oaauth/sdk
pnpm add @oaauth/sdkYou will also need cookie-parser if you are using Express, as the SDK reads and writes cookies via req.cookies.
All configuration is passed to the AuthClient constructor. Sensitive values should come from environment variables — never hardcode credentials.
SDK_KEY=sdk_live_your_key_here
SDK_GATEWAY_URL=https://auth-q03m.onrender.com
OIDC_REDIRECT_URI=http://localhost:4000/callback| Key | Type | Required | Description |
|---|---|---|---|
| SDK_KEY | string | required | Your SDK key from the dashboard. Prefix sdk_live_ for production, sdk_test_ for development. |
| SDK_GATEWAY_URL | string | required | Base URL of the OAauth SDK gateway service. |
| OIDC_REDIRECT_URI | string | required | The callback URL registered in your application. Must exactly match a URI registered in the dashboard. |
The main class. Instantiate once and export — import the instance wherever you need auth logic.
const { AuthClient } = require('@oaauth/sdk');
const auth = new AuthClient({
sdkKey: process.env.SDK_KEY,
gatewayUrl: process.env.SDK_GATEWAY_URL,
redirectUri: process.env.OIDC_REDIRECT_URI,
// Optional — defaults shown
localVerify: true, // verify tokens via JWKS locally
sessionTtl: 604800, // refresh token TTL in seconds (7d)
});An Express request handler. Wire it directly as a route callback — no wrapper needed.
When a user hits this route, the SDK generates a PKCE code verifier and challenge, stores state in a short-lived cookie, and redirects the user to the OIDC provider's authorization endpoint. No configuration beyond the initial AuthClient setup is required.
app.get('/login', auth.login);Exchanges the authorization code for tokens and creates a session in the SDK gateway. Returns the access token, refresh token, and user profile.
app.get('/callback', async (req, res) => {
const { accessToken, refreshToken, user }
= await auth.handleCallbackAndCreateSession(req);
res.cookie('refreshToken', refreshToken, {
httpOnly: true, sameSite: 'lax',
maxAge: 7 * 24 * 60 * 60 * 1000
});
res.json({ accessToken, user });
});| Field | Type | Description |
|---|---|---|
| accessToken | string | Short-lived JWT. Pass as Authorization: Bearer <token>. Expires in 15 minutes. |
| refreshToken | string | Opaque long-lived token. Store in an httpOnly cookie. Used to rotate access tokens. |
| user | object | OIDC user claims: { sub, email, name, roles } |
Middleware factory that validates the access token on each request and populates req.user. Tokens are verified locally by default — no network call required.
// Require authentication
app.get('/me', auth.protect(), (req, res) => {
res.json(req.user); // { sub, email, name, roles }
});
// Optional — req.user is null for unauthenticated requests
app.get('/feed', auth.protect({ optional: true }), handler);
// Apply to an entire router
router.use(auth.protect());| Option | Type | Default | Description |
|---|---|---|---|
| optional | boolean | false | When true, unauthenticated requests pass through with req.user = null instead of returning 401. |
Middleware that checks whether req.user.roles includes the required role. Must be composed after auth.protect().
// Single role
app.delete(
'/admin/users/:id',
auth.protect(),
auth.requireRole('admin'),
deleteUser
);
// Multiple roles — user must have at least one
auth.requireRole(['admin', 'moderator'])A pre-built Express route handler that reads the refresh token from an httpOnly cookie (or request body), rotates the token pair, and sets the new cookie.
// Default — reads from cookie named 'refreshToken'
app.post('/refresh', auth.refreshRoute());
// Custom cookie name
app.post('/refresh', auth.refreshRoute({ cookieName: 'rt' }));A pre-built handler that revokes the current session in the SDK gateway and clears the refresh token cookie.
app.post('/logout', auth.logoutRoute());Fetches all active sessions for a given user from the SDK gateway. Useful for building a "logged-in devices" UI.
app.get('/api/me/sessions',
auth.protect(),
async (req, res) => {
const sessions = await auth.getSessions(req.user.sub);
res.json({ sessions });
}
);| Field | Type | Description |
|---|---|---|
| sessionId | string | Unique session identifier. |
| deviceName | string | Inferred from user-agent string. |
| ip | string | IP address at time of login. |
| lastUsedAt | string | ISO 8601 timestamp of the last token use. |
| expiresAt | string | ISO 8601 expiry timestamp. |
Immediately invalidates every active session for a user. All devices are logged out. Commonly used for security events or account deletion.
app.post('/api/me/logout-all',
auth.protect(),
async (req, res) => {
const result = await auth.revokeAllSessions(req.user.sub);
res.clearCookie('refreshToken');
res.json({ success: true, revoked: result.revoked });
}
);Directly call the SDK gateway to verify an access token and decode its payload.
| Header | Required | Description |
|---|---|---|
| x-sdk-key | required | Your SDK key. |
| Body | Type | Description |
|---|---|---|
| token | string | The access token JWT to verify. |
Manually create a session for a verified user identity. Useful for custom auth flows or migration scenarios.
| Body | Type | Required |
|---|---|---|
| sub | string | required |
| string | required | |
| name | string | required |
Rotate a refresh token. Returns a new access token and refresh token pair. The old refresh token is invalidated immediately.
Revoke a single session by refresh token, or all sessions for a user by userId.
| Time | Method | Endpoint | App | Status | Latency |
|---|---|---|---|---|---|
Connect your logging middleware to populate live data | |||||
Pass as Authorization: Bearer <token> to the portal API.
Inspect, verify, and rotate tokens. All SDK gateway endpoints accessible here.
Paste an access token to verify its signature and decode the payload.