first commit
This commit is contained in:
64
docs/identity/auth/oauth-client/src/utils/jwt.md
Normal file
64
docs/identity/auth/oauth-client/src/utils/jwt.md
Normal file
@@ -0,0 +1,64 @@
|
||||
# jwt
|
||||
|
||||
## Purpose
|
||||
|
||||
Provides minimal JWT decoding utilities for extracting and validating ID-token claims on the client side. Signature verification requires fetching the authorization server's JWKS endpoint and is deliberately out of scope — this module focuses on the claim-level checks that can be performed without cryptographic key material: issuer, audience, expiry, and nonce.
|
||||
|
||||
Separating JWT decoding from signature verification follows the principle of least authority: most OAuth 2.0 client use-cases need only claim extraction for session management, and those that require full verification can layer a JWKS-backed verifier on top.
|
||||
|
||||
## Features
|
||||
|
||||
- `decodeJwt` — splits a JWT and base64url-decodes the header and payload; returns typed `JwtHeader` and `IdTokenClaims`.
|
||||
- `validateIdTokenClaims` — verifies `iss`, `aud`, `exp` (with configurable clock skew), and optional `nonce`.
|
||||
- Throws `OAuthClientError(INVALID_ID_TOKEN)` with structured context on every failure path.
|
||||
|
||||
## Usage: Basic Example
|
||||
|
||||
```ts
|
||||
import { decodeJwt } from "@suaveplan/oauth-client/utils/jwt";
|
||||
|
||||
const { header, claims } = decodeJwt(tokenSet.idToken!);
|
||||
console.log(claims.sub); // subject identifier
|
||||
console.log(claims.email); // user email (if present)
|
||||
```
|
||||
|
||||
## Usage: Advanced Example
|
||||
|
||||
```ts
|
||||
import { decodeJwt, validateIdTokenClaims } from "@suaveplan/oauth-client/utils/jwt";
|
||||
|
||||
const { claims } = decodeJwt(tokenSet.idToken!);
|
||||
|
||||
validateIdTokenClaims(claims, {
|
||||
issuer: "https://accounts.google.com",
|
||||
audience: "my-client-id",
|
||||
nonce: storedNonce,
|
||||
clockSkewSeconds: 60,
|
||||
});
|
||||
|
||||
// Safe to trust claims after validation passes
|
||||
const userId = claims.sub;
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
### `decodeJwt(token: string): { header: JwtHeader; claims: IdTokenClaims; raw: { header: string; payload: string; signature: string } }`
|
||||
|
||||
Decodes a JWT string without verifying its signature.
|
||||
|
||||
- **Throws** `OAuthClientError(INVALID_ID_TOKEN)` when the token does not have exactly three `.`-delimited parts or when either the header or payload is not valid base64url-encoded JSON.
|
||||
|
||||
### `validateIdTokenClaims(claims: IdTokenClaims, options): void`
|
||||
|
||||
Validates standard OIDC ID-token claims.
|
||||
|
||||
- `options.issuer` — expected `iss` value; must match exactly.
|
||||
- `options.audience` — expected `aud` value; must be present in the `aud` array.
|
||||
- `options.nonce?` — when provided, must match `claims.nonce`.
|
||||
- `options.clockSkewSeconds?` — tolerance for clock drift, defaults to 30.
|
||||
- `options.nowSeconds?` — override for the current time (seconds since epoch); useful in tests.
|
||||
- **Throws** `OAuthClientError(INVALID_ID_TOKEN)` for any failed check.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
The `decodeJwt` function uses `base64UrlDecode` from the `pkce` utility to avoid introducing a second base64url implementation. The `TextDecoder` API is universally available in all targeted runtimes. Claims are typed as `IdTokenClaims` which uses an index signature `[key: string]: unknown` to allow non-standard claims without compromising the strict types of standard fields. Clock-skew tolerance applies only to the `exp` check (not `iat`) to avoid accepting tokens from the future.
|
||||
Reference in New Issue
Block a user