Skip to main content

Mounting

Package: @nauth-toolkit/oidc-provider Type: Helpers

The provider is attached to the platform instance, not to your framework's router, so guards, interceptors, pipes and filters never see its endpoints — and no global prefix applies, which is what keeps discovery at the origin root where the issuer advertises it.

Automatic mounting (NestJS)​

OIDCProviderModule.forRoot() attaches the provider itself during module initialisation. A NestJS application needs no OpenID Connect code in main.ts:

src/app.module.ts
@Module({
imports: [AuthModule.forRoot(authConfig), OIDCProviderModule.forRoot(oidcConfig)],
})
export class AppModule {}

Rate limiting is configuration rather than middleware, so it is built from your storage adapter and registered ahead of the provider automatically:

src/config/oidc.config.ts
export const oidcConfig: OIDCProviderModuleOptions = {
issuer: ORIGIN,
pathPrefix: '/oidc',
rateLimit: {
authorize: { max: 60, windowSeconds: 60 },
token: { max: 60, windowSeconds: 60 },
introspection: { max: 600, windowSeconds: 60 },
},
};
oidc-provider ships no rate limiting

Its endpoints sit outside nauth's guard chain, so nothing else covers them. POST /token is otherwise an unauthenticated brute-force surface against client secrets and authorization codes.

This works on both Express and Fastify HTTP drivers. The mount inspects the running driver and picks the matching attach mechanism — app.use() where the instance exposes it, an onRequest hook plus reply.hijack() where it exposes addHook.

What has been verified

Both attach mechanisms are covered by tests against real Express and Fastify instances. The end-to-end combination of NestJS on @nestjs/platform-fastify is not exercised in this repository's test suite — if you run that combination, verify discovery resolves at your origin root before relying on it.

DriverMechanismRequest body at the provider
Expressapp.use() with a path predicateAlready parsed. oidc-provider falls back to req.body, so the upstream parser's size limit applies instead of the provider's.
FastifyRoot-scope onRequest hook with reply.hijack()Unconsumed. The provider keeps its own request-size limit.

Set mount: { enabled: false } to attach the provider yourself with the helpers below.

mountOIDCProviderExpress()​

import { mountOIDCProviderExpress } from '@nauth-toolkit/oidc-provider';
function mountOIDCProviderExpress(
app: MountableApp,
provider: Provider,
options?: { pathPrefix?: string },
): void

Parameters

  • app - The Express application
  • provider - A configured provider
  • options.pathPrefix - The prefix its routes were configured with. Default '/oidc'

Example

src/main.ts
const app = express();
mountOIDCProviderExpress(app, provider, { pathPrefix: '/oidc' });
app.use(express.json());
No URL rewriting

The request is handed over with its path intact, because the provider's routes are configured with the prefix already baked in. app.use('/oidc', provider.callback()) — the recipe in the upstream README — strips the prefix and breaks every URL the provider generates.

mountOIDCProviderNest()​

import { mountOIDCProviderNest } from '@nauth-toolkit/oidc-provider/nestjs';
function mountOIDCProviderNest(
app: INestApplication,
provider: Provider,
options?: { pathPrefix?: string },
): void

Attaches to the underlying platform instance, so setGlobalPrefix() does not apply — the endpoints sit at the origin root exactly as the discovery document advertises them. Call it in main.ts before app.use(json()) and before setGlobalPrefix().

Example

src/main.ts
const app = await NestFactory.create(AppModule, new ExpressAdapter());
mountOIDCProviderNest(app, app.get(NAUTH_OIDC_PROVIDER), { pathPrefix: '/oidc' });
app.use(cookieParser());
app.setGlobalPrefix('api');
NestJS does not need bodyParser: false

oidc-provider falls back to a pre-parsed req.body. Mounting before the parsers still avoids a startup warning and keeps the provider's own request size limit.

isProviderPath()​

import { isProviderPath } from '@nauth-toolkit/oidc-provider';
function isProviderPath(req: { url?: string; path?: string }, prefix: string): boolean

Whether a request belongs to the provider. True for anything under the prefix, and for any /.well-known/ path — discovery lives at the origin root, not under the prefix.

Exported for consumers attaching the provider by hand. On NestJS — including the Fastify HTTP driver — OIDCProviderModule does this for you and there is no need to place anything ahead of your framework's server.

What's Next​