@nestjs/jwt Documentation

repository·master·Indexed 20 days ago

https://github.com/nestjs/jwt

A NestJS module providing JWT (JSON Web Token) utilities by wrapping the jsonwebtoken library. It integrates with the NestJS dependency injection system via JwtModule and JwtService, offering support for static and asynchronous configuration, dynamic secret management through secretOrKeyProvider, and methods for signing, verifying, and decoding tokens.

Tokens
4.7K
Snippets
17
Records
25
Agent score
70%

What's inside @nestjs/jwt

  1. Configure dynamic keys with secretOrKeyProvider

    master

    If you need to manage secrets or keys dynamically (e.g., fetching them from a database or vault), use the secretOrKeyProvider option. This function takes precedence over static secret, publicKey, or privateKey options.

    Note: If you use an asynchronous version of secretOrKeyProvider, you must use the asynchronous .signAsync() and .verifyAsync() methods of JwtService. Using synchronous methods with an async provider will throw an exception.

    JwtModule.register({
       /* Secret has precedence over keys */
      secret: 'hard!to-guess_secret',
    
      /* public key used in asymmetric algorithms (required if non other secrets present) */
      publicKey: '...',
    
      /* private key used in asymmetric algorithms (required if non other secrets present) */
      privateKey: '...',
    
      /* Dynamic key provider has precedence over static secret or pub/private keys */
      secretOrKeyProvider: (
        requestType: JwtSecretRequestType,
        tokenOrPayload: string | Object | Buffer,
        verifyOrSignOrOptions?: jwt.VerifyOptions | jwt.SignOptions
      ) => {
        switch (requestType) {
          case JwtSecretRequestType.SIGN:
            // retrieve signing key dynamically
            return 'privateKey';
          case JwtSecretRequestType.VERIFY:
            // retrieve public key for verification dynamically
            return 'publicKey';
          default:
            // retrieve secret dynamically
            return 'hard!to-guess_secret';
        }
      },
    });
  2. Configure JwtModule asynchronously using registerAsync()

    master

    Use JwtModule.registerAsync() when your configuration depends on other providers (like ConfigService) or needs to be loaded asynchronously. There are three main patterns:

    1. Use a factory

    Use useFactory to define a function that returns the options object. This function can be async and can inject dependencies.

    JwtModule.registerAsync({
      imports: [ConfigModule],
      useFactory: async (configService: ConfigService) => ({
        secret: configService.get<string>('SECRET'),
      }),
      inject: [ConfigService],
    })

    2. Use a class

    Provide a class that implements JwtOptionsFactory. Nest will instantiate this class to create the options.

    class JwtConfigService implements JwtOptionsFactory {
      createJwtOptions(): JwtModuleOptions {
        return {
          secret: 'hard!to-guess_secret'
        };
      }
    }
    
    JwtModule.registerAsync({
      useClass: JwtConfigService
    });

    3. Use an existing provider

    Use useExisting to reuse an already instantiated provider from another module.

    JwtModule.registerAsync({
      imports: [ConfigModule],
      useExisting: ConfigService,
    })
  3. Basic Usage of JwtModule and JwtService

    master

    To use JWT utilities, first import JwtModule into your module using .register() with a secret. Then, inject JwtService into your providers to sign or verify tokens.

    @Module({
      imports: [JwtModule.register({ secret: 'hard!to-guess_secret' })],
      providers: [...],
    })
    export class AuthModule {}
    
    @Injectable()
    export class AuthService {
      constructor(private readonly jwtService: JwtService) {}
    }
  4. JwtService API Reference

    master

    The JwtService is a wrapper around jsonwebtoken. It provides methods to sign, verify, and decode tokens. When calling .sign() or .verify(), you can pass secret, privateKey, or publicKey in the options object to override the module-level configuration (but this will not override a secretOrKeyProvider).

    MethodSignatureDescription
    signsign(payload: string | Object | Buffer, options?: JwtSignOptions): stringImplementation of jsonwebtoken.sign()
    signAsyncsignAsync(payload: string | Object | Buffer, options?: JwtSignOptions): Promise<string>Asynchronous implementation of .sign()
    verifyverify<T extends object = any>(token: string, options?: JwtVerifyOptions): TImplementation of jsonwebtoken.verify()
    verifyAsyncverifyAsync<T extends object = any>(token: string, options?: JwtVerifyOptions): Promise<T>Asynchronous implementation of .verify()
    decodedecode(token: string, options: DecodeOptions): object | stringImplementation of jsonwebtoken.decode()
  5. Configure JwtModule with static options

    master

    When using JwtModule.register(), you provide a JwtModuleOptions object. This object allows you to define the global scope of the module and specify keys for signing and verifying tokens.

    Key configuration properties:

    • global: If true, the JwtModule is registered globally.
    • secret: The secret used for signing or verifying.
    • publicKey / privateKey: Used for asymmetric (RSA/ECDSA) algorithms.
    • signOptions: Options passed to the underlying jsonwebtoken signing process.
    • verifyOptions: Options passed to the underlying jsonwebtoken verification process.
    • secretOrKeyProvider: A function to dynamically retrieve the secret based on the JwtSecretRequestType (SIGN or VERIFY).
    const moduleOptions: JwtModuleOptions = {
      global: true,
      secret: 'my-secret',
      signOptions: { expiresIn: '1h' },
      verifyOptions: { algorithms: ['HS256'] },
    };
  6. Configure JwtModule with async options

    master

    To configure JwtModule using asynchronous providers (e.g., fetching secrets from a database or environment variables), use JwtModuleAsyncOptions. This is typically used with JwtModule.registerAsync().

    Supported patterns:

    • useFactory: A function that returns JwtModuleOptions or a Promise<JwtModuleOptions>. You can use inject to provide dependencies to this factory.
    • useClass: A class that implements the JwtOptionsFactory interface.
    • useExisting: A reference to an existing provider that implements JwtOptionsFactory.

    Note: JwtModuleAsyncOptions also supports extraProviders to add additional providers to the module context.

    // Example using useFactory
    JwtModule.registerAsync({
      global: true,
      useFactory: async (configService: ConfigService) => ({
        secret: configService.get('JWT_SECRET'),
      }),
      inject: [ConfigService],
    });
  7. JwtModule Configuration Options Reference

    master

    The JwtModule accepts an options object for configuration. For optimal performance, it is recommended to pass KeyObject instances (from Node.js crypto module) to secret, privateKey, and publicKey properties.

    // Configuration options for JwtModule
    {
      secret: string | Buffer | object; // Secret for HMAC algorithms
      secretOrKeyProvider: (requestType, tokenOrPayload, options?) => jwt.Secret | Promise<jwt.Secret>; // Dynamic key provider
      signOptions: JwtSignOptions; // Options for signing
      privateKey: string | { key: string; passphrase: string }; // PEM encoded private key for RSA/ECDSA
      publicKey: string; // PEM encoded public key for RSA/ECDSA
      verifyOptions: JwtVerifyOptions; // Options for verification
      // secretOrPrivateKey: DEPRECATED
    }
    
    // Example using KeyObject for performance
    import { createSecretKey } from 'crypto';
    
    new JwtService({
      secret: createSecretKey(Buffer.from('the secret key'))
    });
  8. Handle WrongSecretProviderError

    master

    The WrongSecretProviderError is thrown by the @nestjs/jwt module when a secret provider (used for retrieving signing keys or secrets) fails to provide a valid secret or returns an unexpected value. You can catch this error to handle cases where your secret management logic (e.g., fetching from a vault or environment variable) is misconfigured.

    try {
      // code that triggers JWT signing or verification using a custom secret provider
    } catch (error) {
      if (error instanceof WrongSecretProviderError) {
        // Handle the case where the secret provider returned an invalid secret
      }
    }
  9. Troubleshoot WrongSecretProviderError

    master

    If you encounter a WrongSecretProviderError, it means you are attempting to use an asynchronous secret provider (a function that returns a Promise) with a synchronous method (sign() or verify()).

    Solution:

    • If using sign(), switch to signAsync().
    • If using verify(), switch to verifyAsync().
  10. Sign a JWT with JwtService.sign()

    master

    Use sign() to synchronously create a JSON Web Token from a payload. The payload can be a string, Buffer, or object.

    Important Constraints:

    • If the payload is a string, you are not allowed to provide secret or privateKey within the options object; these must be handled via the service configuration or other mechanisms. Providing them when the payload is a string will result in an error.
    • If you are using an asynchronous secret provider (a function that returns a Promise), you must use signAsync() instead of sign() to avoid a WrongSecretProviderError.
    // Signing an object payload
    const token = jwtService.sign({ userId: 123 });
    
    // Signing with options
    const tokenWithExp = jwtService.sign({ userId: 123 }, { expiresIn: '1h' });
  11. Verify a JWT asynchronously with JwtService.verifyAsync()

    master

    Use verifyAsync() to validate a token when using an asynchronous secret provider. This method returns a Promise<T> containing the decoded payload.

    try {
      const payload = await jwtService.verifyAsync<any>(token);
      console.log(payload.userId);
    } catch (error) {
      // Handle invalid token
    }