### Environment Variable Configuration Example Source: https://github.com/nestjs/jwt/blob/master/_autodocs/key-management.md Shows an example `.env` file structure for configuring JWT-related settings, including the secret, algorithm, and expiration time. ```dotenv JWT_SECRET=your-secret-generated-from-openssl-rand-hex-32 JWT_ALGORITHM=HS256 JWT_EXPIRATION=1h ``` -------------------------------- ### Install NestJS JWT Module Source: https://github.com/nestjs/jwt/blob/master/README.md Install the @nestjs/jwt package using npm. This is the first step to integrate JWT authentication. ```bash npm i --save @nestjs/jwt ``` -------------------------------- ### Commit message samples Source: https://github.com/nestjs/jwt/blob/master/CONTRIBUTING.md Examples of valid commit messages following the project conventions. ```text docs(changelog) update change log to beta.5 ``` ```text fix(@nestjs/core) need to depend on latest rxjs and zone.js The version in our package.json gets copied to the one we publish, and users need the latest of these. ``` -------------------------------- ### JwtConfigService Example Source: https://github.com/nestjs/jwt/blob/master/_autodocs/types.md Example implementation of JwtOptionsFactory. This service asynchronously creates JWT options, fetching the secret from a ConfigService and setting an expiration time. ```typescript @Injectable() export class JwtConfigService implements JwtOptionsFactory { constructor(private configService: ConfigService) {} async createJwtOptions(): Promise { return { secret: await this.configService.get('JWT_SECRET'), signOptions: { expiresIn: '1h' } }; } } ``` -------------------------------- ### Create and Validate JWT Access Tokens Source: https://github.com/nestjs/jwt/blob/master/_autodocs/advanced-usage.md Demonstrates creating JWT access tokens with custom claims and validating them. Includes an example of a guard to protect routes. ```typescript import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common'; import { JwtService } from '@nestjs/jwt'; @Injectable() export class AuthService { constructor(private jwtService: JwtService) {} createAccessToken(userId: string, email: string) { const payload = { sub: userId, // Standard: user identifier email: email, // Custom: user email type: 'access', // Custom: token type iat: Math.floor(Date.now() / 1000) // Issued at }; return this.jwtService.sign(payload, { expiresIn: '15m', issuer: 'auth-service', audience: 'api' }); } validateToken(token: string) { return this.jwtService.verify(token, { issuer: 'auth-service', audience: 'api' }); } } // In guard @Injectable() export class JwtGuard implements CanActivate { constructor(private jwtService: JwtService) {} canActivate(context: ExecutionContext): boolean { const request = context.switchToHttp().getRequest(); const token = request.headers.authorization?.slice(7); try { const payload = this.jwtService.verify(token); request.user = { id: payload.sub, // Extract sub as user ID email: payload.email, type: payload.type }; return true; } catch { return false; } } } ``` -------------------------------- ### Generating Secure HMAC Secrets Source: https://github.com/nestjs/jwt/blob/master/_autodocs/key-management.md Provides command-line examples for generating cryptographically secure random secrets for HMAC algorithms using Node.js or OpenSSL. ```bash # Generate 32 bytes of random data (256 bits) node -e "console.log(require('crypto').randomBytes(32).toString('hex'))" ``` ```bash # Or using OpenSSL openssl rand -hex 32 ``` -------------------------------- ### Register JWT Module with Verification Options Source: https://github.com/nestjs/jwt/blob/master/_autodocs/configuration.md Example of registering the JwtModule with specific verification options, including algorithms, issuer, audience, and clock tolerance. ```typescript JwtModule.register({ secret: 'my-secret', verifyOptions: { algorithms: ['HS256'], issuer: 'auth-service', audience: 'my-app', clockTolerance: 5 // 5 second tolerance } }); ``` -------------------------------- ### Register JwtModule Synchronously Source: https://github.com/nestjs/jwt/blob/master/_autodocs/api-reference/jwt-module.md Use JwtModule.register() for synchronous configuration. Provide a secret key for basic setup. ```typescript import { Module } from '@nestjs/common'; import { JwtModule } from '@nestjs/jwt'; @Module({ imports: [ JwtModule.register({ secret: 'hard!to-guess_secret' }) ] }) export class AuthModule {} ``` -------------------------------- ### Async Key Provider for JWKS Source: https://github.com/nestjs/jwt/blob/master/_autodocs/advanced-usage.md Fetch keys from external services on demand using an asynchronous `secretOrKeyProvider`. This example demonstrates fetching public keys from a JWKS endpoint for verification and using a local private key for signing. Remember to use `signAsync()` and `verifyAsync()` when employing an async provider. ```typescript import { JwtSecretRequestType } from '@nestjs/jwt'; JwtModule.register({ secretOrKeyProvider: async ( requestType: JwtSecretRequestType, tokenOrPayload: string | object | Buffer ) => { if (requestType === JwtSecretRequestType.VERIFY) { // Fetch public key from JWKS endpoint const jwks = await fetch('https://auth.example.com/.well-known/jwks.json') .then(r => r.json()); // Extract key ID from token header if (typeof tokenOrPayload === 'string') { const decoded = jwt.decode(tokenOrPayload, { complete: true }); const kid = decoded?.header.kid; const key = jwks.keys.find(k => k.kid === kid); if (!key) throw new Error('Key not found'); return key.x5c[0]; // Return certificate } } // For signing, use local key return await keyManagement.getPrivateKey(); } }); ``` -------------------------------- ### Dynamic Secret Resolution with secretOrKeyProvider Source: https://github.com/nestjs/jwt/blob/master/_autodocs/advanced-usage.md Use `secretOrKeyProvider` to select signing keys at runtime based on token context or environment. This example shows how to return the current signing secret for signing operations and dynamically select a public key for verification based on the token's header. ```typescript import { JwtSecretRequestType } from '@nestjs/jwt'; import jwt from 'jsonwebtoken'; JwtModule.register({ secretOrKeyProvider: ( requestType: JwtSecretRequestType, tokenOrPayload: string | object | Buffer, options?: jwt.VerifyOptions | jwt.SignOptions ) => { if (requestType === JwtSecretRequestType.SIGN) { // Return current signing secret return process.env.JWT_SIGNING_SECRET; } if (requestType === JwtSecretRequestType.VERIFY) { // Decode header to check kid (key id) if (typeof tokenOrPayload === 'string') { const header = jwt.decode(tokenOrPayload, { complete: true })?.header; const keyId = header?.kid; // Return appropriate public key based on key ID const keyMap = { 'current': process.env.JWT_PUBLIC_KEY, 'previous': process.env.JWT_PUBLIC_KEY_OLD }; return keyMap[keyId] || keyMap['current']; } return process.env.JWT_PUBLIC_KEY; } } }); ``` -------------------------------- ### Create a new git branch Source: https://github.com/nestjs/jwt/blob/master/CONTRIBUTING.md Use this command to start a new feature or fix branch from the master branch. ```shell git checkout -b my-fix-branch master ``` -------------------------------- ### Configure JWT with Configuration Service Class Source: https://github.com/nestjs/jwt/blob/master/_autodocs/configuration.md Implement JwtOptionsFactory with a custom service class to centralize JWT configuration logic. This approach is useful for more complex or reusable configuration setups. ```typescript import { Injectable } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; import { JwtModuleOptions, JwtOptionsFactory } from '@nestjs/jwt'; @Injectable() export class JwtConfigService implements JwtOptionsFactory { constructor(private configService: ConfigService) {} createJwtOptions(): JwtModuleOptions { return { secret: this.configService.get('JWT_SECRET'), signOptions: { expiresIn: this.configService.get('JWT_EXPIRATION', '1h'), algorithm: 'HS256' }, verifyOptions: { algorithms: ['HS256'] } }; } } @Module({ imports: [ JwtModule.registerAsync({ useClass: JwtConfigService }) ] }) export class AuthModule {} ``` -------------------------------- ### Verify a JWT Token Source: https://github.com/nestjs/jwt/blob/master/_autodocs/quick-start.md Validate incoming JWT tokens in guards or middleware to ensure their authenticity. This example shows how to verify a token and throw an exception if it's invalid. ```typescript import { Injectable } from '@nestjs/common'; import { JwtService } from '@nestjs/jwt'; import { UnauthorizedException } from '@nestjs/common'; @Injectable() export class JwtAuthGuard { constructor(private jwtService: JwtService) {} validateToken(token: string) { try { return this.jwtService.verify(token); } catch (error) { throw new UnauthorizedException('Invalid token'); } } } ``` -------------------------------- ### Complete JWT Authentication Flow in NestJS Source: https://github.com/nestjs/jwt/blob/master/_autodocs/quick-start.md This snippet demonstrates the full setup for JWT authentication in NestJS. It includes the AuthModule for configuration, AuthService for token generation and validation, JwtGuard for protecting routes, and AuthController for handling login and profile requests. Ensure the JWT secret and expiration are configured appropriately. ```typescript // auth.module.ts import { Module } from '@nestjs/common'; import { JwtModule } from '@nestjs/jwt'; import { AuthService } from './auth.service'; import { AuthController } from './auth.controller'; @Module({ imports: [ JwtModule.register({ secret: 'secret-key', signOptions: { expiresIn: '1h' } }) ], controllers: [AuthController], providers: [AuthService], exports: [JwtModule] }) export class AuthModule {} // auth.service.ts import { Injectable } from '@nestjs/common'; import { JwtService } from '@nestjs/jwt'; @Injectable() export class AuthService { constructor(private jwtService: JwtService) {} async login(userId: string) { const payload = { sub: userId, username: 'john' }; return { access_token: this.jwtService.sign(payload) }; } async validateToken(token: string) { return this.jwtService.verify(token); } } // auth.guard.ts import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common'; import { JwtService } from '@nestjs/jwt'; @Injectable() export class JwtGuard implements CanActivate { constructor(private jwtService: JwtService) {} canActivate(context: ExecutionContext): boolean { const request = context.switchToHttp().getRequest(); const auth = request.headers.authorization; if (!auth?.startsWith('Bearer ')) { return false; } const token = auth.slice(7); try { request.user = this.jwtService.verify(token); return true; } catch { return false; } } } // auth.controller.ts import { Controller, Post, UseGuards, Get, Request, HttpCode } from '@nestjs/common'; import { AuthService } from './auth.service'; import { JwtGuard } from './auth.guard'; @Controller('auth') export class AuthController { constructor(private authService: AuthService) {} @Post('login') @HttpCode(200) async login() { return this.authService.login('user123'); } @Get('profile') @UseGuards(JwtGuard) getProfile(@Request() req) { return req.user; // User from JWT } } ``` -------------------------------- ### Basic NestJS JWT Module Setup Source: https://github.com/nestjs/jwt/blob/master/_autodocs/README.md Register the JwtModule in your application's auth module, providing a secret key and sign options for token generation. ```typescript import { Module } from '@nestjs/common'; import { JwtModule } from '@nestjs/jwt'; @Module({ imports: [ JwtModule.register({ secret: 'your-secret-key', signOptions: { expiresIn: '1h' } }) ] }) export class AuthModule {} ``` -------------------------------- ### Register JWT Module Globally Source: https://github.com/nestjs/jwt/blob/master/_autodocs/api-reference/jwt-module.md Set `global: true` to make `JwtService` available throughout your application without additional imports. This example shows how to register the JWT module with a global flag and a secret key. ```typescript import { Module } from '@nestjs/common'; import { JwtModule } from '@nestjs/jwt'; @Module({ imports: [ JwtModule.register({ global: true, secret: 'hard!to-guess_secret' }) ] }) export class AppModule {} ``` -------------------------------- ### Initialize JwtService with KeyObject Source: https://github.com/nestjs/jwt/blob/master/README.md Use Node.js crypto module to create KeyObject instances for improved performance. ```typescript import { createSecretKey } from 'crypto'; new JwtService({ secret: createSecretKey(Buffer.from('the secret key')) }); ``` -------------------------------- ### Secret Provider Callback Example Source: https://github.com/nestjs/jwt/blob/master/_autodocs/types.md Example of a secretOrKeyProvider callback function that uses JwtSecretRequestType to determine the secret. It returns 'signing_secret' for signing and 'verification_secret' for verification. ```typescript const secretOrKeyProvider = ( requestType: JwtSecretRequestType, tokenOrPayload: string | object | Buffer, options?: jwt.VerifyOptions | jwt.SignOptions ) => { if (requestType === JwtSecretRequestType.SIGN) { return 'signing_secret'; } return 'verification_secret'; }; ``` -------------------------------- ### Generating RSA Keys for Asymmetric Encryption Source: https://github.com/nestjs/jwt/blob/master/_autodocs/key-management.md Provides command-line instructions using OpenSSL to generate RSA private and public keys. Includes options for generating keys with and without passphrase protection. ```bash # Generate private key (4096-bit) openssl genrsa -out private.pem 4096 ``` ```bash # Extract public key openssl rsa -in private.pem -pubout -out public.pem ``` ```bash # With passphrase protection openssl genrsa -out private.pem 4096 openssl genrsa -passout pass:your-passphrase -out private.pem 4096 ``` -------------------------------- ### Async Key Provider Error Handling Source: https://github.com/nestjs/jwt/blob/master/_autodocs/errors.md Shows how to register an async key provider and catch potential Promise rejections during JWT operations like signAsync or verifyAsync. ```typescript JwtModule.register({ secretOrKeyProvider: async (requestType) => { const result = await externalService.getKey(); if (!result) { throw new Error('Key not found'); } return result; } }); // Promise rejection will be caught in verifyAsync/signAsync try { const token = await jwtService.signAsync(payload); } catch (error) { // Errors from secretOrKeyProvider or JWT operations console.error(error); } ``` -------------------------------- ### Decode JWT Token Source: https://github.com/nestjs/jwt/blob/master/_autodocs/INDEX.md Use the `decode` method of `JwtService` to get the JWT payload without verifying the signature. Useful for inspecting token contents. ```typescript this.jwtService.decode(token); ``` -------------------------------- ### Store JWT Keys in .env for Development Source: https://github.com/nestjs/jwt/blob/master/_autodocs/key-management.md For development, store your private and public keys in a .env file. Ensure this file is added to your .gitignore to prevent accidental exposure. ```bash # .env (add to .gitignore) PRIVATE_KEY=$(cat private.pem) PUBLIC_KEY=$(cat public.pem) ``` -------------------------------- ### JwtModuleAsyncOptions Interface Source: https://github.com/nestjs/jwt/blob/master/_autodocs/types.md Defines the structure for asynchronous options when registering the JwtModule. Use this when you need to provide JWT options dynamically, for example, by injecting configuration values. ```typescript interface JwtModuleAsyncOptions extends Pick { global?: boolean; useExisting?: Type; useClass?: Type; useFactory?: (...args: any[]) => Promise | JwtModuleOptions; inject?: any[]; extraProviders?: Provider[]; } ``` -------------------------------- ### Using Async Sign and Verify Methods Source: https://github.com/nestjs/jwt/blob/master/_autodocs/api-reference/jwt-service.md When using an async secretOrKeyProvider, always use the `signAsync()` and `verifyAsync()` methods provided by the JwtService. The synchronous `sign()` and `verify()` methods will log a warning and throw an error. ```typescript // Use async methods const token = await jwtService.signAsync(payload); const decoded = await jwtService.verifyAsync(token); ``` -------------------------------- ### Async JWT Module Configuration with ConfigService Source: https://github.com/nestjs/jwt/blob/master/_autodocs/quick-start.md Configure the JWT module asynchronously by loading the secret key from environment variables or a configuration service. This is useful for managing secrets securely. ```typescript import { Module } from '@nestjs/common'; import { ConfigModule, ConfigService } from '@nestjs/config'; import { JwtModule } from '@nestjs/jwt'; @Module({ imports: [ ConfigModule.forRoot(), JwtModule.registerAsync({ imports: [ConfigModule], useFactory: async (config: ConfigService) => ({ secret: config.get('JWT_SECRET') }), inject: [ConfigService] }) ] }) export class AuthModule {} ``` -------------------------------- ### Using Passphrase-Protected Private Keys Source: https://github.com/nestjs/jwt/blob/master/_autodocs/key-management.md Demonstrates how to configure the `JwtModule` when the private key is protected by a passphrase. It uses Node.js `crypto` module to load the key securely from an environment variable. ```typescript import { createPrivateKey } from 'crypto'; import { readFileSync } from 'fs'; const privateKey = createPrivateKey({ key: readFileSync('private.pem'), format: 'pem', passphrase: process.env.PRIVATE_KEY_PASSPHRASE }); JwtModule.register({ privateKey: privateKey, publicKey: readFileSync('public.pem'), signOptions: { algorithm: 'RS256' } }); ``` -------------------------------- ### Register JwtModule Asynchronously with UseExisting Source: https://github.com/nestjs/jwt/blob/master/_autodocs/api-reference/jwt-module.md Configure JWT asynchronously using 'useExisting' to reuse an already configured provider, such as ConfigService, for JWT options. ```typescript @Module({ imports: [ JwtModule.registerAsync({ imports: [ConfigModule], useExisting: ConfigService }) ] }) export class AuthModule {} ``` -------------------------------- ### Configure JWT Module with RSA Asymmetric Keys Source: https://github.com/nestjs/jwt/blob/master/_autodocs/configuration.md Register the JWT module using RSA private and public keys for asymmetric signing. Load keys from files using fs.readFileSync. ```typescript JwtModule.register({ privateKey: fs.readFileSync('private.pem'), publicKey: fs.readFileSync('public.pem') }); ``` -------------------------------- ### Configure JwtModule asynchronously with a class Source: https://github.com/nestjs/jwt/blob/master/README.md Implement the JwtOptionsFactory interface in a class to provide configuration options. ```typescript JwtModule.registerAsync({ useClass: JwtConfigService }); ``` ```typescript class JwtConfigService implements JwtOptionsFactory { createJwtOptions(): JwtModuleOptions { return { secret: 'hard!to-guess_secret' }; } } ``` -------------------------------- ### Default JWT Module Import Source: https://github.com/nestjs/jwt/blob/master/_autodocs/modules.md The recommended way to import the JwtModule and JwtService for general use. ```typescript import { JwtModule, JwtService, JwtModuleOptions } from '@nestjs/jwt'; ``` -------------------------------- ### Generating ECDSA Keys for Asymmetric Encryption Source: https://github.com/nestjs/jwt/blob/master/_autodocs/key-management.md Provides command-line instructions using OpenSSL to generate ECDSA private and public keys using the P-256 curve. ```bash # Generate private key (P-256 curve) openssl ecparam -name prime256v1 -genkey -noout -out private.pem ``` ```bash # Extract public key openssl ec -in private.pem -pubout -out public.pem ``` -------------------------------- ### Graceful Key Rotation Strategy Source: https://github.com/nestjs/jwt/blob/master/_autodocs/key-management.md Implement a JwtOptionsFactory to handle key rotation. This strategy allows signing with the current private key and verifying tokens using either the current or previous public keys based on the token's header. ```typescript import { Injectable } from '@nestjs/common'; import { JwtModuleOptions, JwtOptionsFactory, JwtSecretRequestType } from '@nestjs/jwt'; import * as jwt from 'jsonwebtoken'; import { readFileSync } from 'fs'; @Injectable() export class KeyRotationService implements JwtOptionsFactory { createJwtOptions(): JwtModuleOptions { return { secretOrKeyProvider: (requestType, tokenOrPayload) => { if (requestType === JwtSecretRequestType.SIGN) { // Always sign with current key return this.getCurrentPrivateKey(); } if (requestType === JwtSecretRequestType.VERIFY) { if (typeof tokenOrPayload === 'string') { // Check token header for key version const decoded = jwt.decode(tokenOrPayload, { complete: true }); const keyVersion = decoded?.header?.kid; // Accept both current and previous key const key = this.getPublicKey(keyVersion); if (!key) { throw new Error('Unknown key version'); } return key; } } }, signOptions: { algorithm: 'RS256', expiresIn: '1h', keyid: this.getCurrentKeyVersion() } }; } private getCurrentPrivateKey() { // Always signing with current key return this.loadKey('current-private.pem'); } private getPublicKey(version?: string) { // Accept current and previous versions const keyVersion = version || this.getCurrentKeyVersion(); try { return this.loadKey(`${keyVersion}-public.pem`); } catch { // Fallback to current if version not found return this.loadKey('current-public.pem'); } } private getCurrentKeyVersion(): string { return process.env.JWT_KEY_VERSION || 'current'; } private loadKey(path: string) { return readFileSync(`/keys/${path}`); } } ``` -------------------------------- ### Multi-Tenant Token Verification and Signing Source: https://github.com/nestjs/jwt/blob/master/_autodocs/advanced-usage.md This service handles JWTs for multiple tenants, verifying tokens against tenant-specific secrets and signing new tokens with the appropriate secret. It decodes tokens to check tenant claims before verification. ```typescript import { Injectable, UnauthorizedException } from '@nestjs/common'; import { JwtService } from '@nestjs/jwt'; @Injectable() export class TenantJwtService { constructor(private jwtService: JwtService) {} verifyTenantToken(token: string, tenantId: string) { // Decode to check claims const decoded = this.jwtService.decode<{ tenant: string }>(token); if (decoded?.tenant !== tenantId) { throw new UnauthorizedException('Token invalid for this tenant'); } // Verify with tenant-specific secret const tenantSecret = this.getTenantSecret(tenantId); return this.jwtService.verify(token, { secret: tenantSecret }); } signTenantToken(payload: object, tenantId: string) { const tenantSecret = this.getTenantSecret(tenantId); return this.jwtService.sign( { ...payload, tenant: tenantId }, { secret: tenantSecret, expiresIn: '1h' } ); } private getTenantSecret(tenantId: string): string { // Get tenant-specific secret from database or cache return `tenant-${tenantId}-secret`; } } ``` -------------------------------- ### Configure JWT with Existing Provider Source: https://github.com/nestjs/jwt/blob/master/_autodocs/configuration.md Use an existing provider that implements JwtOptionsFactory to configure JWT. This is suitable when the configuration logic is already managed elsewhere and can be injected. ```typescript @Module({ imports: [ ConfigModule.forRoot(), JwtModule.registerAsync({ imports: [ConfigModule], useExisting: ConfigService // ConfigService must implement JwtOptionsFactory }) ] }) export class AuthModule {} ``` -------------------------------- ### Register JwtModule with Sign/Verify Options Source: https://github.com/nestjs/jwt/blob/master/_autodocs/api-reference/jwt-module.md Configure JWT signing and verification options like expiration time and algorithms during synchronous registration. ```typescript JwtModule.register({ secret: 'secret_key', signOptions: { expiresIn: '1h', algorithm: 'HS256' }, verifyOptions: { algorithms: ['HS256'] } }) ``` -------------------------------- ### Configure JwtModule asynchronously with a factory Source: https://github.com/nestjs/jwt/blob/master/README.md Use a factory function to provide configuration options, optionally injecting dependencies. ```typescript JwtModule.registerAsync({ useFactory: () => ({ secret: 'hard!to-guess_secret' }) }); ``` ```typescript JwtModule.registerAsync({ imports: [ConfigModule], useFactory: async (configService: ConfigService) => ({ secret: configService.get('SECRET'), }), inject: [ConfigService], }), ``` -------------------------------- ### Configure JwtModule asynchronously with an existing provider Source: https://github.com/nestjs/jwt/blob/master/README.md Reuse an existing provider instance to supply configuration options. ```typescript JwtModule.registerAsync({ imports: [ConfigModule], useExisting: ConfigService, }), ``` -------------------------------- ### Register JWT Module with KeyObject (Recommended) Source: https://github.com/nestjs/jwt/blob/master/_autodocs/configuration.md Configure the JwtModule using KeyObject instances for enhanced performance. This method supports both symmetric secrets and asymmetric keys. ```typescript import { createPrivateKey, createPublicKey, createSecretKey } from 'crypto'; import { readFileSync } from 'fs'; JwtModule.register({ secretKey: createSecretKey(Buffer.from('secret')), // OR privateKey: createPrivateKey({ key: readFileSync('private.pem'), format: 'pem' }), publicKey: createPublicKey({ key: readFileSync('public.pem'), format: 'pem' }) }); ``` -------------------------------- ### Register JwtModule Asynchronously with Factory and Dependencies Source: https://github.com/nestjs/jwt/blob/master/_autodocs/api-reference/jwt-module.md Configure JWT asynchronously using 'useFactory' with injected dependencies like ConfigService to dynamically set the secret and sign options. ```typescript JwtModule.registerAsync({ imports: [ConfigModule], useFactory: async (configService: ConfigService) => ({ secret: configService.get('JWT_SECRET'), signOptions: { expiresIn: configService.get('JWT_EXPIRATION') } }), inject: [ConfigService] }) ``` -------------------------------- ### verify() Source: https://github.com/nestjs/jwt/blob/master/_autodocs/api-reference/jwt-service.md Verifies and decodes a JWT token synchronously. It returns the decoded payload, allowing for immediate use of the token's claims. ```APIDOC ## verify() ### Description Verifies and decodes a JWT token synchronously. Returns the decoded payload. ### Method `verify` ### Parameters #### Token - **token** (string) - Required - The JWT token to verify #### Options - **options** (JwtVerifyOptions) - Optional - Verification options to override module defaults ### Returns `T` - The decoded and verified token payload, typed as generic `T` ### Throws - `WrongSecretProviderError` - Called when module uses async `secretOrKeyProvider` - `TokenExpiredError` - Token has expired (from jsonwebtoken) - `JsonWebTokenError` - Token is malformed or signature is invalid - `NotBeforeError` - Token is not yet valid (nbf claim) ### Example ```typescript @Injectable() export class AuthGuard implements CanActivate { constructor(private jwtService: JwtService) {} canActivate(context: ExecutionContext): boolean { const request = context.switchToHttp().getRequest(); const token = request.headers.authorization?.split(' ')[1]; try { const payload = this.jwtService.verify<{ sub: string }>(token); request.user = payload; return true; } catch (err) { throw new UnauthorizedException(); } } } ``` ``` -------------------------------- ### Configure JWT Module with Secret or Private Key Source: https://github.com/nestjs/jwt/blob/master/_autodocs/configuration.md Demonstrates the deprecated method of using `secretOrPrivateKey` and the correct approach using `secret` for HMAC or `privateKey` for asymmetric algorithms. ```typescript // ❌ DEPRECATED JwtModule.register({ secretOrPrivateKey: 'secret' }); // ✅ CORRECT JwtModule.register({ secret: 'secret' // for HMAC // OR privateKey: 'private-key' // for asymmetric }); ``` -------------------------------- ### Register JwtModule Asynchronously with Extra Providers Source: https://github.com/nestjs/jwt/blob/master/_autodocs/api-reference/jwt-module.md When registering asynchronously using 'useFactory', you can include 'extraProviders' to make additional services available within the factory function's scope. ```typescript JwtModule.registerAsync({ imports: [DatabaseModule], useFactory: async (db: DatabaseService) => ({ secret: await db.getJwtSecret() }), inject: [DatabaseService], extraProviders: [SomeCustomProvider] }) ``` -------------------------------- ### JwtVerifyOptions Source: https://github.com/nestjs/jwt/blob/master/_autodocs/types.md Options for verifying JWT operations, extending jsonwebtoken's VerifyOptions with specific overrides for secret or public key. ```APIDOC ## JwtVerifyOptions ### Description Options for verifying JWT operations, extending jsonwebtoken's `VerifyOptions` with specific overrides for secret or public key. ### Fields #### `secret` - Type: `string | Buffer` - Required: No - Description: Override module secret for this verification only. #### `publicKey` - Type: `string | Buffer` - Required: No - Description: Override module public key for this verification only. #### Other Fields - All `jwt.VerifyOptions` fields are supported, including `algorithms`, `audience`, `issuer`, `ignoreExpiration`, `ignoreNotBefore`, `clockTimestamp`, `clockTolerance`, `subject`. ``` -------------------------------- ### JwtOptionsFactory Source: https://github.com/nestjs/jwt/blob/master/_autodocs/types.md Interface for factory classes providing JWT configuration asynchronously. ```APIDOC ## Interface: JwtOptionsFactory ### Description Interface for factory classes providing JWT configuration asynchronously. ### Methods #### createJwtOptions - **Signature**: `(): Promise | JwtModuleOptions` - **Returns**: Configuration object (sync or async). ### Example Usage ```typescript @Injectable() export class JwtConfigService implements JwtOptionsFactory { constructor(private configService: ConfigService) {} async createJwtOptions(): Promise { return { secret: await this.configService.get('JWT_SECRET'), signOptions: { expiresIn: '1h' } }; } } ``` ``` -------------------------------- ### Push branch to GitHub Source: https://github.com/nestjs/jwt/blob/master/CONTRIBUTING.md Uploads the local branch to the remote repository. ```shell git push origin my-fix-branch ``` -------------------------------- ### Use JWT Service for Signing and Verifying Source: https://github.com/nestjs/jwt/blob/master/_autodocs/00-START-HERE.md Inject the JwtService into your application services to generate JWTs upon login and verify incoming tokens. The sign method creates a token with a user ID payload, and the verify method decodes and validates a token. ```typescript import { Injectable } from '@nestjs/common'; import { JwtService } from '@nestjs/jwt'; @Injectable() export class AuthService { constructor(private jwtService: JwtService) {} login(userId: string) { return this.jwtService.sign({ sub: userId }); } verify(token: string) { return this.jwtService.verify(token); } } ``` -------------------------------- ### Implementing Token Blacklisting for Logout Source: https://github.com/nestjs/jwt/blob/master/_autodocs/key-management.md Provides a `TokenBlacklistService` and `AuthService` to manage token revocation. This prevents logged-out users from using their existing tokens. ```typescript @Injectable() export class TokenBlacklistService { private blacklist = new Set(); blacklistToken(token: string) { this.blacklist.add(token); } isBlacklisted(token: string): boolean { return this.blacklist.has(token); } } @Injectable() export class AuthService { constructor( private jwtService: JwtService, private blacklist: TokenBlacklistService ) {} logout(token: string) { this.blacklist.blacklistToken(token); } verify(token: string) { if (this.blacklist.isBlacklisted(token)) { throw new UnauthorizedException('Token has been revoked'); } return this.jwtService.verify(token); } } ``` -------------------------------- ### Synchronously Signing a JWT Source: https://github.com/nestjs/jwt/blob/master/_autodocs/api-reference/jwt-service.md Use the sign() method to create a JWT synchronously. This is suitable for scenarios where an asynchronous operation is not required. Ensure the payload and options are correctly formatted. ```typescript @Injectable() export class AuthService { constructor(private jwtService: JwtService) {} createToken(userId: string) { const payload = { sub: userId, name: 'John Doe' }; return this.jwtService.sign(payload, { expiresIn: '1h' }); } } ``` -------------------------------- ### Using Environment Variables for JWT Secrets Source: https://github.com/nestjs/jwt/blob/master/_autodocs/key-management.md Illustrates how to securely load JWT secrets from environment variables using `ConfigModule` and `ConfigService`. This prevents hardcoding sensitive information directly in the application code. ```typescript // ❌ BAD - Secret in code JwtModule.register({ secret: 'my-super-secret-key-12345' }); ``` ```typescript // ✅ GOOD - Secret from environment import { ConfigService } from '@nestjs/config'; JwtModule.registerAsync({ imports: [ConfigModule], useFactory: (config: ConfigService) => ({ secret: config.get('JWT_SECRET', 'fallback-dev-secret') }), inject: [ConfigService] }); ``` -------------------------------- ### Import JWT Module Interfaces Source: https://github.com/nestjs/jwt/blob/master/_autodocs/modules.md Imports all necessary interfaces and types for JWT module configuration and usage. ```typescript import { JwtModuleOptions, JwtSignOptions, JwtVerifyOptions, JwtSecretRequestType, JwtOptionsFactory, JwtModuleAsyncOptions, GetSecretKeyResult } from '@nestjs/jwt'; ``` -------------------------------- ### Asymmetric Key Rotation Service Source: https://github.com/nestjs/jwt/blob/master/_autodocs/advanced-usage.md This service implements JwtOptionsFactory to provide dynamic private and public keys for JWT signing and verification. It supports rotating keys by updating the currentKeyId. Ensure that the private and public key files exist at the specified paths. ```typescript import { createPrivateKey, createPublicKey } from 'crypto'; import { readFileSync } from 'fs'; @Injectable() export class KeyRotationService implements JwtOptionsFactory { private currentKeyId = 'key-2024-01'; private keys = { 'key-2024-01': { privateKey: createPrivateKey({ key: readFileSync('keys/2024-01-private.pem'), format: 'pem' }), publicKey: createPublicKey({ key: readFileSync('keys/2024-01-public.pem'), format: 'pem' }) }, 'key-2024-02': { privateKey: createPrivateKey({ key: readFileSync('keys/2024-02-private.pem'), format: 'pem' }), publicKey: createPublicKey({ key: readFileSync('keys/2024-02-public.pem'), format: 'pem' }) } }; createJwtOptions(): JwtModuleOptions { return { privateKey: this.keys[this.currentKeyId].privateKey, publicKey: this.keys[this.currentKeyId].publicKey, signOptions: { algorithm: 'RS256', expiresIn: '1h', keyid: this.currentKeyId }, secretOrKeyProvider: (requestType, tokenOrPayload) => { if (requestType === JwtSecretRequestType.VERIFY) { // Decode to get key ID if (typeof tokenOrPayload === 'string') { const header = jwt.decode(tokenOrPayload, { complete: true })?.header; const keyId = header?.kid || this.currentKeyId; return this.keys[keyId]?.publicKey || this.keys[this.currentKeyId].publicKey; } } return this.keys[this.currentKeyId].privateKey; } }; } rotateKey(newKeyId: string) { if (!this.keys[newKeyId]) { throw new Error(`Key ${newKeyId} not found`); } this.currentKeyId = newKeyId; } } ``` -------------------------------- ### Generate Access and Refresh Tokens Source: https://github.com/nestjs/jwt/blob/master/_autodocs/README.md Use this pattern to create JWT access and refresh tokens for user authentication. The tokens are signed with a secret and have specified expiration times. ```typescript import { Injectable, UnauthorizedException, } from '@nestjs/common'; import { JwtService } from '@nestjs/jwt'; @Injectable() export class AuthService { constructor(private jwtService: JwtService) {} login(userId: string) { const payload = { sub: userId }; return { access_token: this.jwtService.sign(payload, { expiresIn: '15m' }), refresh_token: this.jwtService.sign(payload, { expiresIn: '7d' }), }; } } ``` -------------------------------- ### Async Dynamic Secret Key Provider Source: https://github.com/nestjs/jwt/blob/master/_autodocs/configuration.md Configure an asynchronous secret key provider to fetch keys from external services. Ensure to use signAsync and verifyAsync methods when employing an async provider. ```typescript JwtModule.register({ secretOrKeyProvider: async ( requestType: JwtSecretRequestType, tokenOrPayload: string | object | Buffer, options?: jwt.VerifyOptions | jwt.SignOptions ) => { if (requestType === JwtSecretRequestType.VERIFY) { // Fetch key from external service const key = await keyManagementService.getPublicKey(); return key; } // Async provider: must use signAsync/verifyAsync return await keyManagementService.getPrivateKey(); } }); // Use async methods const token = await jwtService.signAsync(payload); const decoded = await jwtService.verifyAsync(token); ``` -------------------------------- ### Retrieve JWT Keys from HashiCorp Vault Source: https://github.com/nestjs/jwt/blob/master/_autodocs/key-management.md Implement a service to fetch JWT keys from HashiCorp Vault. This approach is recommended for production environments using Vault for secrets management. ```typescript import axios from 'axios'; @Injectable() export class VaultService { async getSecret(path: string): Promise { const response = await axios.get( `${process.env.VAULT_ADDR}/v1/${path}`, { headers: { 'X-Vault-Token': process.env.VAULT_TOKEN } } ); return response.data.data.data.value; } } JwtModule.registerAsync({ useFactory: async (vault: VaultService) => ({ privateKey: await vault.getSecret('secret/jwt/private-key'), publicKey: await vault.getSecret('secret/jwt/public-key') }), inject: [VaultService] }); ``` -------------------------------- ### Create JWT Provider Configuration Source: https://github.com/nestjs/jwt/blob/master/_autodocs/api-reference/jwt-providers.md Generates provider configuration for dependency injection during synchronous module registration. This function is typically called internally by `JwtModule.register()`. ```typescript export function createJwtProvider(options: JwtModuleOptions): any[] ``` ```typescript { provide: JWT_MODULE_OPTIONS, useValue: options || {} }] ``` ```typescript // Internal usage in JwtModule.register() static register(options: JwtModuleOptions): DynamicModule { return { module: JwtModule, global: options.global, providers: createJwtProvider(options) // Called here }; } ``` -------------------------------- ### Performance Optimization with KeyObject Source: https://github.com/nestjs/jwt/blob/master/_autodocs/advanced-usage.md Improve JWT signing and verification performance by using Node.js `KeyObject` instances for secrets and keys instead of raw buffers or strings. This reduces parsing overhead. ```typescript import { createSecretKey, createPrivateKey, createPublicKey } from 'crypto'; import { readFileSync } from 'fs'; import { JwtModule } from '@nestjs/jwt'; const jwtModule = JwtModule.register({ // Pre-created KeyObject instead of raw PEM secretKey: createSecretKey( Buffer.from('your-secret-key') ), // OR for asymmetric privateKey: createPrivateKey({ key: readFileSync('private.pem'), format: 'pem', passphrase: 'passphrase-if-needed' }), publicKey: createPublicKey({ key: readFileSync('public.pem'), format: 'pem' }), signOptions: { algorithm: 'RS256', expiresIn: '1h' } }); ``` -------------------------------- ### Register JwtModule Asynchronously with Factory Source: https://github.com/nestjs/jwt/blob/master/_autodocs/api-reference/jwt-module.md Use JwtModule.registerAsync() with a 'useFactory' option for asynchronous configuration. This allows injecting dependencies to determine configuration values. ```typescript JwtModule.registerAsync({ useFactory: () => ({ secret: 'hard!to-guess_secret' }) }) ``` -------------------------------- ### Commit message format template Source: https://github.com/nestjs/jwt/blob/master/CONTRIBUTING.md The required structure for all commit messages to ensure proper changelog generation. ```text ():