# OIDC

> OIDC at the Askr server boundary, with validated input and explicit failure states.

Source: [https://askrjs.com/docs/authentication/oidc](https://askrjs.com/docs/authentication/oidc)

Status: stable. Packages: @askrjs/auth/oidc.

**Published packages are authoritative.** Examples may lag behind a published contract. When guidance differs, verify the exports and TypeScript declarations in your installed package, then file an issue.

## Example

Use discovery and authorization-code flow helpers at the server boundary; validate state, nonce, redirect URI, and issuer on callback.

```tsx
import { createOidcClient } from '@askrjs/auth/oidc';

const oidc = await createOidcClient({
  issuer: env.OIDC_ISSUER,
  clientId: env.OIDC_CLIENT_ID,
  redirectUri: env.OIDC_REDIRECT_URI,
});
```

## Discovery

createOidcClient(options: OidcClientOptions) takes issuer, clientId, an optional clientSecret, redirectUri, scopes, and an injectable fetch, and returns an OidcClient. Its discover() method fetches the provider's OidcProviderMetadata - authorization_endpoint, token_endpoint, jwks_uri, and the optional userinfo_endpoint and end_session_endpoint - so you don't hardcode those URLs per provider.

## Authorization flow

createAuthorizationRequest(options?: {state?, nonce?, codeVerifier?, loginHint?}) builds the redirect URL for the provider's authorization endpoint and returns it alongside the state, nonce, and PKCE codeVerifier it used - generating any of the three for you if you don't supply them. The caller's only job is to persist those values (typically in a short-lived cookie) so they're available when the browser comes back to the callback route.

## Callback validation

Once the browser returns with a code, exchangeCode({code, state, request: {state, nonce, codeVerifier}}) posts to the provider's token endpoint and resolves to { tokens, principal } - it already validates the ID token internally (signature, issuer, audience, and the nonce you stored earlier) as part of the exchange, rejecting with an OidcClientError('invalid-id-token', ...) if any of those checks fail. There's no separate validateOidcIdToken() call to make on this path; that function exists for validating an ID token you obtained some other way, not as a required second step after exchangeCode().

## Session establishment

Neither createOidcClient nor validateOidcIdToken create an application session - that's left to you deliberately, since how you store sessions is covered under Model and Sessions. After the code exchange and ID token check succeed, a callback handler typically creates a SessionStore entry or issues your own JWT via createJwtIssuer, then sets a cookie with @askrjs/server's ctx.setCookie(), the same way the framework's built-in auth routes do.

## Documentation navigation

[Previous](https://askrjs.com/docs/authentication/jwt/index.md) | [Next](https://askrjs.com/docs/authentication/framework-routes/index.md)
