Git Product home page Git Product logo

jwt's Introduction

Nest Logo

A progressive Node.js framework for building efficient and scalable server-side applications.

NPM Version Package License NPM Downloads Coverage Discord Backers on Open Collective Sponsors on Open Collective

Description

JWT utilities module for Nest based on the jsonwebtoken package.

Installation

$ npm i --save @nestjs/jwt

Usage

Import JwtModule:

@Module({
  imports: [JwtModule.register({ secret: 'hard!to-guess_secret' })],
  providers: [...],
})
export class AuthModule {}

Inject JwtService:

@Injectable()
export class AuthService {
  constructor(private readonly jwtService: JwtService) {}
}

Secret / Encryption Key options

If you want to control secret and key management dynamically you can use the secretOrKeyProvider function for that purpose. You also can use asynchronous version of secretOrKeyProvider. NOTE: For asynchronous version of secretOrKeyProvider, synchronous versions of .sign() and .verify() 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';
    }
  },
});

Async options

Quite often you might want to asynchronously pass your module options instead of passing them beforehand. In such case, use registerAsync() method, that provides a couple of various ways to deal with async data.

1. Use factory

JwtModule.registerAsync({
  useFactory: () => ({
    secret: 'hard!to-guess_secret'
  })
});

Obviously, our factory behaves like every other one (might be async and is able to inject dependencies through inject).

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

2. Use class

JwtModule.registerAsync({
  useClass: JwtConfigService
});

Above construction will instantiate JwtConfigService inside JwtModule and will leverage it to create options object.

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

3. Use existing

JwtModule.registerAsync({
  imports: [ConfigModule],
  useExisting: ConfigService,
}),

It works the same as useClass with one critical difference - JwtModule will lookup imported modules to reuse already created ConfigService, instead of instantiating it on its own.

API Spec

The JwtService uses jsonwebtoken underneath.

jwtService.sign(payload: string | Object | Buffer, options?: JwtSignOptions): string

The sign method is an implementation of jsonwebtoken .sign(). Differing from jsonwebtoken it also allows an additional secret, privateKey, and publicKey properties on options to override options passed in from the module. It only overrides the secret, publicKey or privateKey though not a secretOrKeyProvider. NOTE: Will throw an exception for asynchronous version of secretOrKeyProvider;

jwtService.signAsync(payload: string | Object | Buffer, options?: JwtSignOptions): Promise<string>

The asynchronous .sign() method.

jwtService.verify<T extends object = any>(token: string, options?: JwtVerifyOptions): T

The verify method is an implementation of jsonwebtoken .verify(). Differing from jsonwebtoken it also allows an additional secret, privateKey, and publicKey properties on options to override options passed in from the module. It only overrides the secret, publicKey or privateKey though not a secretOrKeyProvider. NOTE: Will throw an exception for asynchronous version of secretOrKeyProvider;

jwtService.verifyAsync<T extends object = any>(token: string, options?: JwtVerifyOptions): Promise<T>

The asynchronous .verify() method.

jwtService.decode(token: string, options: DecodeOptions): object | string

The decode method is an implementation of jsonwebtoken .decode().

The JwtModule takes an options object:

  • secret is either a string, buffer, or object containing the secret for HMAC algorithms
  • secretOrKeyProvider function with the following signature (requestType, tokenOrPayload, options?) => jwt.Secret | Promise<jwt.Secret> (allows generating either secrets or keys dynamically)
  • signOptions read more
  • privateKey PEM encoded private key for RSA and ECDSA with passphrase an object { key, passphrase } read more
  • publicKey PEM encoded public key for RSA and ECDSA
  • verifyOptions read more
  • secretOrPrivateKey (DEPRECATED!) read more

Support

Nest is an MIT-licensed open source project. It can grow thanks to the sponsors and support by the amazing backers. If you'd like to join them, please read more here.

Stay in touch

License

Nest is MIT licensed.

jwt's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

jwt's Issues

Decode JWT without verifying secret

I'm submitting a...


[ ] Regression 
[ ] Bug report
[ ] Feature request
[x] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.

Current behavior

I am trying to decode a signed token without verifying the JWT. Is this possible?

Nest can't resolve dependencies of the JwtService (?). Please make sure that the argument JWT_MODULE_OPTIONS at index [0] is available in the JwtModule context.

I'm receiving the error in the title and nothing I got from searching the internet helped.
These are the relevant parts of my code:

import { Injectable } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { ForbiddenException } from '@nestjs/common';

@Injectable()
export class TokenService {
  constructor(private readonly jwt: JwtService) {}

  async sign(payload: object) {
    return this.jwt.sign({ payload });
  }

  async verify(token: string) {
    try {
      const { payload } = this.jwt.verify(token);
      return payload;
    } catch (exc) {
      throw new ForbiddenException();
    }
  }
}
import { Module } from '@nestjs/common'
import { TokenService } from './token.service'
import { ConfigModule, ConfigService } from '@nestjs/config'
import { JwtModule } from '@nestjs/jwt'

@Module({
  providers: [TokenService],
  imports: [
    JwtModule.registerAsync({
      imports: [ConfigModule],
      inject: [ConfigService],
      useFactory: async (config: ConfigService) => ({
        secret: config.get<string>('SECRET'),
      }),
    }),
  ],
  exports: [TokenService],
})
export class TokenModule {}
import { Module } from '@nestjs/common'
import { AppController } from './app.controller'
import { AppService } from './app.service'
import { TokenModule } from './token/token.module'
import { AuthModule } from './auth/auth.module'
import { ProfileModule } from './profile/profile.module'
import { MongooseModule } from '@nestjs/mongoose'
import { ConfigModule, ConfigService } from '@nestjs/config'
import { JwtModule } from '@nestjs/jwt'

@Module({
  imports: [
    MongooseModule.forRoot('mongodb://localhost/db-name'),
    ConfigModule.forRoot(),
    JwtModule,
    TokenModule,
    AuthModule,
    ProfileModule,
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

JwtModule.register() The method didn't work

JwtModule.register({ secret: "configuration.auth.secretKey", signOptions: { expiresIn: '1s' }, })

This token never expires
Then I tried the secret change, and token is still valid

jwt module shoud extends ConfigurableModuleClass

Is there an existing issue for this?

  • I have searched the existing issues

Current behavior

JwtModule does not use the nestjs v9 ModuleOptionsBuilder. That said we cannot use the providers from the parent module when we want to pass the options from a parent module (as describe here: nestjs/nest#9935).

Minimum reproduction code

nestjs/nest#9935

Steps to reproduce

Try to use this kind of configuration described in the merged pull request.

         JwtModule.registerAsync({
          useFactory(opt: AuthenticationOptions) {
            return opt.jwtOptions;
          },
          inject: [AuthenticationOptions],
        }),

When using this code we cannot inject JwtService in our service from our parent module

Expected behavior

Allow provideInjectionTokensFrom to be able to use the config providers from a parent module

Package version

9.0.0

NestJS version

9.0.11

Node.js version

16.15.1

In which operating systems have you tested?

  • macOS
  • Windows
  • Linux

Other

No response

BigInt not supported

Is there an existing issue for this?

  • I have searched the existing issues

Current behavior

When signing a jwt token with a BigInt, it will not be singed correctly.

For example: 869976676795383809 will be signed as 869976676795383800

Minimum reproduction code

Not neccesary

Steps to reproduce

No response

Expected behavior

It should just be signed as 869976676795383800

Package version

latest

NestJS version

No response

Node.js version

No response

In which operating systems have you tested?

  • macOS
  • Windows
  • Linux

Other

No response

Error: Nest can't resolve dependencies of the UsersService (?). Please make sure that the argument studentsModel at index [0] is available in the AppModule context

Am trying JWT in my code and i got an error of -
:Error: Nest can't resolve dependencies of the UsersService (?). Please make sure that the argument studentsModel at index [0] is available in the AppModule context

Potential solutions:

  • If studentsModel is a provider, is it part of the current AppModule?
  • If studentsModel is exported from a separate @module, is that module imported within AppModule?
    @module({
    imports: [ /* the Module containing studentsModel */ ]
    })

But i didn't understand how to solve this.

Decode method : options is not optional


[ ] Regression 
[x] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.

Current behavior

When using the decode method, the 2nd argument 'options' is not optional as it is in the jsonwebtoken package.

Override module options

I'm submitting a...


[ ] Regression 
[ ] Bug report
[x] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.

Current behavior

Currently, there is no way that when we sign or verify a token, we can override the options provided in JwtModule.register() or JwtModule.registerAsync().

Expected behavior

There should be a way to override the options.

What is the motivation / use case for changing the behavior?

When we need to use the same JwtService to create/verify different tokens with different secrets (refreshToken vs accessToken)

Environment


Nest version: X.Y.Z

 
For Tooling issues:
- Node version: XX  
- Platform:  

Others:

Refresh tokens

I'm submitting a...


[ ] Regression 
[ ] Bug report
[x] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.

Current behavior

When the access token expires we are forced to show the user a login form again so they can manually authenticate again, rather than automaticly renewing the token using a refresh token.

Expected behavior

When the token expires we should get a 401, whereafter we try to refresh the access token using our refresh token, if succeeded we should get a new set of keys, else we should invalidate both tokens forcing the user to login again.

What is the motivation / use case for changing the behavior?

Using refresh tokens has been pretty standardized within the use of JWT's, we are making a unnatural flow without them.

https://auth0.com/blog/refresh-tokens-what-are-they-and-when-to-use-them/

Unexpected behavior when getting a value from .env file for expiresIn property via the ConfigModule / ConfigService

Is there an existing issue for this?

  • I have searched the existing issues

Current behavior

It assigns zero to the expiresIn property, instead of the number of seconds (JWT_EXP=60) provided in the parameter in the .env file. However, when an s is added to the parameter value (JWT_EXP=60s) it works OK.

Some more details
The strange thing happens at that line
signOptions: { expiresIn: configService.get('JWT_EXP', 60) },

It was refusing to get the JWT_EXP value from the .env file:
JWT_EXP=60
until added the ‘s’ as the seconds indicator, so I changed it to:
JWT_EXP=60s
After that it works OK

Surprisingly, I also noticed that when the JWT_EXP env variable is missing, e.g. I renamed it to
JWT_EXPXXX=60s
the default number value provided as second parameter in configService.get, works OK as it is expected.

Just also to mention, that as an error message I got back trying to solve the issue, the
"expiresIn" should be a number of seconds or string representing a timespan eg: "1d", "20h", 60 ….

Minimum reproduction code

https://gist.github.com/zzpzaf/7fc9bba6c294674b3fa355f44e7cc52e, https://gist.github.com/zzpzaf/27ce9f2847ce01952e510ff70d1edb3c, https://gist.github.com/zzpzaf/d558b7376e03dfb18f986c0a20bf2bb0

Steps to reproduce

No response

Expected behavior

It should read the number of seconds provided correctly, as expiration time, without s - seconds indicator

Package version

8.0.0

NestJS version

8.1.5

Node.js version

16.11.0

In which operating systems have you tested?

  • macOS
  • Windows
  • Linux

Other

I also have a post at Discord

Jwt is expired,but filter can't catch this exception 401 but return 500

I'm submitting a...


[ ] Regression 
[x] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.

Current behavior

image

when jwt expired,I get a error like this

[Nest] 16572   - 2020-02-14 13:41:37   [ExceptionsHandler] Object:
{
  "statusCode": 401,
  "error": "Unauthorized"
}
 +5577099ms
Error: [object Object]
    at MixinAuthGuard.handleRequest (D:\Code\nest-test\node_modules\_@nestjs_passport@6.1.1@@nestjs\passport\dist\auth.guard.js:63:30)
    at D:\Code\nest-test\node_modules\_@nestjs_passport@6.1.1@@nestjs\passport\dist\auth.guard.js:47:120
    at D:\Code\nest-test\node_modules\_@nestjs_passport@6.1.1@@nestjs\passport\dist\auth.guard.js:78:24
...

and response is

{"statusCode":500,"message":"Internal server error"}

so, how can I use filter catch this error

Expected behavior

use filter catch this exception 401

Minimal reproduction of the problem with instructions

What is the motivation / use case for changing the behavior?

Environment


Nest version: 6.8.2

@nest/password version: 6.1.1
@nest/jwt version: 6.1.1
 
For Tooling issues:
- Node version: XX  
- Platform:  Windows

Others:

vulnerability in dependancy jsonwebtoken <=8.5.1

Is there an existing issue for this?

  • I have searched the existing issues

Current behavior

There is a security issue in dependency jsonwebtoken
Updating to jsonwebtoken's latest version 9.0.0 resolves the vulnerability
Vulnerability details : GHSA-27h2-hvpr-p74q

Minimum reproduction code

GHSA-27h2-hvpr-p74q

Steps to reproduce

No response

Expected behavior

updating jsonwebtoken to latest version 9.0.0

Package version

9.0.0

NestJS version

No response

Node.js version

No response

In which operating systems have you tested?

  • macOS
  • Windows
  • Linux

Other

No response

Unable to verify tokens when using Buffer/base64 encoded public key

I'm submitting a...

  • Bug report

Current behavior

Unable to verify tokens when using Buffer/base64 encoded public key -> throws Invalid algorithm error.

Expected behavior

Public key as Buffer (direct binary array) should be supported.

Minimal reproduction of the problem with instructions

Use the following AuthModule:

import { Module } from '@nestjs/common';
import { JwtModule } from '@nestjs/jwt';
// import pemtools from 'pemtools';

let publicKey: string | Buffer | null = process.env.JWT_PUBLIC_KEY;
if (process.env.JWT_PUBLIC_KEY && !process.env.JWT_PUBLIC_KEY.startsWith('-----')) {
  publicKey = Buffer.from(process.env.JWT_PUBLIC_KEY, 'base64');
  // Workaround:
  // publicKey = pemtools(publicKey, 'PUBLIC KEY').toString();
}
// console.debug('publicKey=', publicKey);

@Module({
  imports: [
    JwtModule.register({
      publicKey,
    })
  ],
})
export class AuthModule {}

When publicKey is a buffer, jwtService.verify(...) will always fail due to 'Invalid algorithm', however if we pass a PEM-encoded string, it will work.

What is the motivation / use case for changing the behavior?

One-line Base64 encoded string is much easier to put into environment variable (12-factor app principle) than PEM-encoded multiline string.

Environment

Nest version: nestjs/jwt 7.1.0

For Tooling issues:

  • Node version: 12.19.0
  • Platform: Ubuntu 20.04.1

Others:

Workaround is to use npm package pemtools:

import pemtools from 'pemtools';

let publicKey: string | Buffer | null = process.env.JWT_PUBLIC_KEY;
if (process.env.JWT_PUBLIC_KEY && !process.env.JWT_PUBLIC_KEY.startsWith('-----')) {
  publicKey = Buffer.from(process.env.JWT_PUBLIC_KEY, 'base64');
  // Workaround:
  publicKey = pemtools(publicKey, 'PUBLIC KEY').toString();
}

However this is unnecessary as what it does is re-encoding Buffer which is already binary into PEM-encoded string which will be decoded into binary string again.

Related to #94.

Version 8.0.0 does not seem to have correctly built

I'm submitting a...


[ ] Regression 
[x] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.

Current behavior

import { JwtService } from '@nestjs/jwt';

This produces error:

Module '"@nestjs/jwt"' has no exported member 'JwtService'.

Expected behavior

There should be no error.

Minimal reproduction of the problem with instructions

Install version 8.0.0 using npm i -S @nestjs/jwt and try importing anything from the package.

What is the motivation / use case for changing the behavior?

Package unusable.

Environment


Nest version: 8.0.2
For Tooling issues:
- Node version: v15.6.0
- Platform:  Windows

Others:
I noticed that in `node_modules\@nestjs\jwt`, there is no `dist\` directory.

JwtService stopped working after upgrading dependencies

I'm submitting a...


[ ] Regression 
[X] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.

Current behavior

After upgrading @nestjs deps, diff here:

   "dependencies": {
-    "@nestjs/common": "^6.2.0-next.2",
-    "@nestjs/core": "^6.2.0-next.2",
-    "@nestjs/graphql": "^6.2.2",
-    "@nestjs/graphql": "^6.2.2",
-    "@nestjs/jwt": "^6.1.0",
+    "@nestjs/common": "^6.4.1",
+    "@nestjs/core": "^6.4.1",
+    "@nestjs/graphql": "^6.2.4",
+    "@nestjs/jwt": "^6.1.1",
     "@nestjs/passport": "^6.1.0",
-    "@nestjs/platform-express": "^6.1.1",
+    "@nestjs/platform-express": "^6.4.1",

JwtService suddenly stopped being available in DI. It worked flawlessly before with this setup.

Getting error Nest can't resolve dependencies of the ContextFactory (AuthService, ?). Please make sure that the argument at index [1] is available in the ServerModule context.

Context factory:

import { Injectable } from '@nestjs/common';
import { AuthService } from 'src/auth/services/auth.service';
import { JwtService } from '@nestjs/jwt';
import { Request } from 'express';
import { IUserIdentity } from 'src/api/common/interfaces/user-identity.interface';
import { IGraphqlRequestContext } from './context.interface';
import { AuthenticationError } from 'apollo-server-core';

@Injectable()
export class ContextFactory {
  constructor(
    private readonly authService: AuthService,
    private readonly jwtService: JwtService,
  ) {}

...

Server module:

import { Module } from '@nestjs/common';
import { ContextFactory } from './context.factory';
import { AuthModule } from 'src/auth/auth.module';
import { DatabaseModule } from 'src/database/database.module';

@Module({
  imports: [DatabaseModule, AuthModule],
  providers: [ContextFactory],
  exports: [ContextFactory],
})
export class ServerModule {}

Auth Module:

import { Module } from '@nestjs/common';
import { JwtModule, JwtService } from '@nestjs/jwt';
import { AuthService } from './services/auth.service';
import { JwtStrategy } from './services/jwt.strategy';
import { PassportModule } from '@nestjs/passport';
import { UserModule } from 'src/api/modules/users/user.module';
import { Types } from 'src/common/types';
import { IConfig } from 'src/config/config.interface';
import { ConfigModule } from 'src/config/config.module';
import { DatabaseModule } from 'src/database/database.module';
import { tokenProviders } from './providers/token.providers';
import { EmailModule } from 'src/emails/email.module';

@Module({
  imports: [
    DatabaseModule,
    PassportModule.register({ defaultStrategy: 'jwt' }),
    JwtModule.registerAsync({
      imports: [ConfigModule],
      inject: [Types.CONFIG],
      useFactory: async (config: IConfig) => {
        return {
          secret: config.secretKey,
          signOptions: {
            expiresIn: config.accessTokenExpiresIn,
          },
        };
      },
    }),
    UserModule,
    EmailModule,
  ],
  providers: [AuthService, JwtStrategy, ...tokenProvider],
  exports: [PassportModule, AuthService],
})
export class AuthModule {}

Expected behavior

I would expect this to work as previously, I don't understand the cause in change of this behaviour. I didn't find any updated instructions in NestJS docs last time I checked.

Environment


Nest version: 6.4.1

Packages:
  "@nestjs/common": "^6.4.1",
  "@nestjs/core": "^6.4.1",
  "@nestjs/graphql": "^6.2.4",
  "@nestjs/jwt": "^6.1.1",
  "@nestjs/passport": "^6.1.0",
  "@nestjs/platform-express": "^6.4.1",

RS256 - token created, but can't access protected routes

I'm submitting a...


[ ] Regression 
[x] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.

Current behavior

When I try to use RS256 algorithm for JWT it issues tokens, but I can't access route protected by guards.

Expected behavior

When used RS256 issue token, I should be able to access protected routes with it.

Minimal reproduction of the problem with instructions

Here is a repo to reproduce https://github.com/kscerbiakas/nestjs-auth

there is .env.example file where you can find all commands needed to reproduce the issue.
Rename it to .env

Create database.

Database runs on PORT 3308 if you choose to connect via UI or CLI.

docker run --name nestjs-mysql -e MYSQL_USER=nestjs   -e MYSQL_PASSWORD=nestjs -e MYSQL_DATABASE=nestjs   -p 3308:3306 -d mysql/mysql-server:5.7

Generate keys for RS256

ssh-keygen -t rsa -b 4096 -m PEM -f jwtKey.key
openssl rsa -in jwtKey.key -pubout -outform PEM -out jwtKey.key.pub

put them next to package.json

Create user via POSTING to the route http://localhost:8080/api/v1/users following:

{
  "email": "[email protected]",
  "password": "securePassword"
}

Get token via POSTING to http://localhost:8080/api/v1/auth/token

{
  "email": "[email protected]",
  "password": "securePassword"
}

Protected GET route http://localhost:8080/api/v1/auth/data should return JSON

{"hello": "'hello"}

instead it returns HTTP 401

{
  "statusCode": 401,
  "error": "Unauthorized"
}

All routes are in auth.controller.ts

For testing purposes you can switch JWT algorithms in .env by editing DEFAULT_AUTH_ALGORITHM variable.

Any input to solve this problem would be very helpful .

Environment


Nest version: 5.4.0


For Tooling issues:
- Node version: 10.6  
- Platform: MAC 

Others:

npm
WebStorm

Misleading error message on deprecated feature

I'm submitting a...


[ ] Regression 
[X] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.

Current behavior

Using deprecated secretOrPrivateKey option in register method.

    JwtModule.register({
      secretOrPrivateKey: 'ssshhhh',
      signOptions: { expiresIn: '60s' },
    })

causes error message: [JwtService] "secretOrPrivateKey" has been deprecated, please use the new explicit "secretOrKeyProvider" or use "privateKey"/"publicKey" exclusively.

The error message omits the third option: explicit "secret" option. For example, this is valid:

    JwtModule.register({
      secret: 'ssshhhh',
      signOptions: { expiresIn: '60s' },
    })

Expected behavior

Error message should read:
[JwtService] "secretOrPrivateKey" has been deprecated, please use the new explicit "secretOrKeyProvider" or use "secret" or "privateKey"/"publicKey" exclusively.

Minimal reproduction of the problem with instructions

What is the motivation / use case for changing the behavior?

Environment


Nest version: X.Y.Z

 
For Tooling issues:
- Node version: XX  
- Platform:  

Others:

expiresIn error

I'm submitting a...


[ ] Regression 
[ * ] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.

Current behavior

Expected behavior

Minimal reproduction of the problem with instructions

What is the motivation / use case for changing the behavior?

Environment


Nest version: X.Y.Z

 
For Tooling issues:
- Node version: XX  
- Platform:  

Others:

I set like this:


   JwtModule.registerAsync({
      useFactory() {
        return {
          secret: process.env.SECRET_OR_KEY,
          signOptions: { expiresIn: 300*1000 }
        }
      }
     })

but every time running, give me this error

[Nest] 2696   - 2021/06/22 上午11:53:07   [ExceptionsHandler] invalid expiresIn option for string payload +5673ms
Error: invalid expiresIn option for string payload
    at Object.module.exports [as sign] (D:\js\proposal\node_modules\jsonwebtoken\sign.js:128:22)
    at JwtService.sign (D:\js\proposal\node_modules\@nestjs\jwt\dist\jwt.service.js:27:20)
    at AdminController.login (D:\js\proposal\dist\main.js:586:41)
    at D:\js\proposal\node_modules\@nestjs\core\router\router-execution-context.js:38:29
    at processTicksAndRejections (internal/process/task_queues.js:93:5)
    at async D:\js\proposal\node_modules\@nestjs\core\router\router-execution-context.js:46:28
    at async D:\js\proposal\node_modules\@nestjs\core\router\router-proxy.js:9:17


if  I remove like this
 signOptions: { expiresIn:   }
everything is ok

so, how can I write the expiresIn ? for example, 5 minites

TypeError: metatype is not a constructor

Hi Team,

My code was running properly and all of a sudden I'm getting this error.

[Nest] 10348 - 16/02/2020, 11:14:40 pm [ExceptionHandler] metatype is not a constructor +17ms TypeError: metatype is not a constructor at Injector.instantiateClass (C:\Users\susha\Documents\Nest.js\Task Management\node_modules\@nestjs\core\injector\injector.js:288:19) at callback (C:\Users\susha\Documents\Nest.js\Task Management\node_modules\@nestjs\core\injector\injector.js:75:41) at processTicksAndRejections (internal/process/task_queues.js:97:5) at async Injector.resolveConstructorParams (C:\Users\susha\Documents\Nest.js\Task Management\node_modules\@nestjs\core\injector\injector.js:116:24) at async Injector.loadInstance (C:\Users\susha\Documents\Nest.js\Task Management\node_modules\@nestjs\core\injector\injector.js:79:9) at async Injector.loadInjectable (C:\Users\susha\Documents\Nest.js\Task Management\node_modules\@nestjs\core\injector\injector.js:32:9) at async Promise.all (index 0) at async InstanceLoader.createInstancesOfInjectables (C:\Users\susha\Documents\Nest.js\Task Management\node_modules\@nestjs\core\injector\instance-loader.js:57:9) at async C:\Users\susha\Documents\Nest.js\Task Management\node_modules\@nestjs\core\injector\instance-loader.js:28:13 at async Promise.all (index 6)

I've tried installing and uninstalling the node_modules it still didn't help.

I can't find the problem too using the error stack.

Could anyone please check where is it breaking?

This is the link to my repository in which I'm facing the issue.

Thanks!

secretOrPrivateKey must have a value

Is there an existing issue for this?

  • I have searched the existing issues

Current behavior

"@nestjs/core": "^9.0.0",
"@nestjs/jwt": "^9.0.0",

registering module this way:
JwtModule.registerAsync({
useFactory: () => ({
secret: 'some_random_secret',
signOptions: {
expiresIn: '30m'
},

But when trying to sign with JwtService I am recieving error: "message": "secretOrPrivateKey must have a value",

What can cause this problem?

Minimum reproduction code

{ "message": "secretOrPrivateKey must have a value", "success": false }

Steps to reproduce

No response

Expected behavior

Expected behavior is not to ask about secretOrPrivateKey that is a deprecated option

Package version

9.0.0

NestJS version

9.0.0

Node.js version

16

In which operating systems have you tested?

  • macOS
  • Windows
  • Linux

Other

No response

secretOrPrivateKey has a minimum key size of 2048 bits for RS256 after upgrade to nest/jwt 10.0.2

Is there an existing issue for this?

  • I have searched the existing issues

Current behavior

failed to generate token and throw exception secretOrPrivateKey has a minimum key size of 2048 bits for RS256. this issue only happen when running inside docker alpine (FROM node:18.14-alpine3.17) normal run on my local

Minimum reproduction code

Sorry repo in my company git

Steps to reproduce

  1. upgrade package.json like below :

    "@nestjs/jwt": "10.0.2"
    "passport-jwt": "^4.0.1",
    "@types/passport-jwt": "^3.0.8",

Expected behavior

normal like "@nestjs/jwt": "9.0.0",

Package version

10.0.2

NestJS version

9.3.9

Node.js version

18.14

In which operating systems have you tested?

  • macOS
  • Windows
  • Linux

Other

No response

Updating `jsonwebtoken` dependency

Is there an existing issue that is already proposing this?

  • I have searched the existing issues

Is your feature request related to a problem? Please describe it

This moring we had a failed dependency security scanning, due to an high vulrnerability risk with this package. By investigatigating, we got to the conclusion that the package jsonwebtoken has that vulnerability, which is a dependacy of this package.
This is the link to the vulnerability: GHSA-27h2-hvpr-p74q .

There is a new version of the jsonwebtoken which should resolve this issue. So my question is: Will @nestjs/jwt package support the newest version of jsonwebtoken which is v9.0.0 in near future?

Thank you in advance.

Describe the solution you'd like

The dependency jsonwebtoken should be updated to version v9.0.0

Teachability, documentation, adoption, migration strategy

No response

What is the motivation / use case for changing the behavior?

This will directly affect our production build, but passing the security scan, since we would love to continue using this package.

Unknown authentication strategy "jwt"

I'm submitting a...


[ ] Regression 
[ X ] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.

Current behavior

In error
Unknown authentication strategy "jwt"

Expected behavior

jwt beeing an known authentication strategy

Minimal reproduction of the problem with instructions

authModule:

@Module({
  providers: [
    AuthenticationService,
    JwtStrategy
  ],
  imports: [
    JwtModule.register({
      secret: jwtConstants.secret,
      signOptions: { expiresIn: "1d" },
    }),
    UsersModule,
  ],
  exports: [AuthenticationService, JwtModule]
})
export class AuthenticationModule {}

User Module

@Module({
  imports: [TypeOrmModule.forFeature([User])],
  providers: [UsersService],
  controllers: [UsersController],
  exports: [UsersService]
})
export class UsersModule {}

users controller

@UseGuards(JwtAuthGuard)
  @Get()
  async getAll(){
    return this.usersService.findAll();
  }

JwtAuthGuard

@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {}

What is the motivation / use case for changing the behavior?

Making use of the jwt authentication guard

Environment


Nest version: 6.11.8

 
For Tooling issues:
- Node version: 10.15.1
- Platform:  Windows

Others:
Followed along the docs. Made sure that the Strategy is in the providers.
Doesnt work in app.controller.ts either

Action Required: Fix Renovate Configuration

There is an error with this repository's Renovate configuration that needs to be fixed. As a precaution, Renovate will stop PRs until it is resolved.

Error type: undefined. Note: this is a nested preset so please contact the preset author if you are unable to fix it yourself.

Unable to verify tokens when using bas64 encoded secrets

Bug Report

Current behavior

It looks like tokens cannot be verified if the secret is Base64 encoded. The issue is caused by the implementation of the verify method. Link to Method

  verify<T extends object = any>(
    token: string,
    options?: jwt.VerifyOptions
  ): T {
    const verifyOptions = this.mergeJwtOptions(options, 'verifyOptions');
    const secret = this.getSecretKey(
      token,
      options,
      'publicKey',
      JwtSecretRequestType.VERIFY
    );

    return jwt.verify(token, secret.toString(), verifyOptions) as T;
  }

The issue is being caused by the stringification of the secret in this line:

return jwt.verify(token, secret.toString(), verifyOptions) as T;

Check out the typescript definitions for the jsonwebtoken library, the underlying library for nestjs/jwt:

export type Secret =
    | string
    | Buffer
    | { key: string | Buffer; passphrase: string };

And here is the Typescript definition for the verify implementation:

export function verify(
    token: string,
    secretOrPublicKey: string | Buffer,
    options?: VerifyOptions,
): object | string;

And here are the type definitions for the nestjs/jwt:

export interface JwtModuleOptions {
  signOptions?: jwt.SignOptions;
  secret?: string | Buffer;   // <-------  THIS ONE HERE
  publicKey?: string | Buffer;
  privateKey?: jwt.Secret;  // <----- ALSO, THIS ONE HERE
  /**
   * @deprecated
   */
  secretOrPrivateKey?: jwt.Secret;
  secretOrKeyProvider?: (
    requestType: JwtSecretRequestType,
    tokenOrPayload: string | object | Buffer,
    options?: jwt.VerifyOptions | jwt.SignOptions
  ) => jwt.Secret;
  verifyOptions?: jwt.VerifyOptions;
}

The verify method CAN take a buffer but it is being stringified here. This causes keys that are Base64 encoded to fail always when used with the nestjs/jwt package.

Expected behavior

JWT should be verified correctly if the the secret is of Buffer type. The buffer should not be using toString() in the verify method.

Minimal reproduction of the problem with instructions

Gist of code to verify problematic code

What is the motivation / use case for changing the behavior?

We would love to stick to the nest ecosystem, but our company uses base64 buffers for creating JWT's.

Environment


Nest version: 6.7.2

 
For Tooling issues:
- Node version: 10.15.1  
- Platform:  Mac 

Others:

secretOrPrivateKey must have a value

Is there an existing issue for this?

  • I have searched the existing issues

Current behavior

This code doesn't work, When calling the sign method,thorw an error: secretOrPrivateKey must have a value

// auth.module.ts
@Module({
  imports: [
    JwtModule.register({
      secret: 'test',
        signOptions: {
          expiresIn: '60s'
        }
    })
  ],
  controllers: [ AuthController ],
  providers: [ LocalStrategy, ConfigService, JwtService, AuthService ] 
})
// auth.service.ts
import { Injectable } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';

@Injectable()
export class AuthService {
  constructor(
    private readonly jwtService: JwtService
  ) { }

  async login(user: {username: string, id: string}) {
    const payload = { username: user.username, sub: user.id };
    return {
      access_token: this.jwtService.sign(payload)
    };
  }
}

image

but if pass parameters to sign method, It work

import { Injectable } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';

@Injectable()
export class AuthService {
  constructor(
    private readonly jwtService: JwtService
  ) { }

  async login(user: {username: string, id: string}) {
    const payload = { username: user.username, sub: user.id };
    return {
      access_token: this.jwtService.sign(payload, {
        secret: 'test',
        expiresIn: '60s'
      })
    };
  }
}

Will it be caused by version differences between various dependencies?
image

Minimum reproduction code

none

Steps to reproduce

No response

Expected behavior

Normal return jwt

Package version

10.0.2

NestJS version

9.0.0

Node.js version

16.14.2

In which operating systems have you tested?

  • macOS
  • Windows
  • Linux

Other

I wrote it according to the official document, so I'm a little confused

NestJS can't resolve dependencies of the JWT_MODULE_OPTIONS

I'm submitting a...


[ ] Regression 
[x] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.

Current behavior

Nest can't resolve dependencies in JWT_MODULE_OPTIONS

Expected behavior

Dependencies are resolved.

Minimal reproduction of the problem with instructions

import { JwtModule } from '@nestjs/jwt';
@Module({
    imports: [
        TypeOrmModule.forFeature([User, Role]),
        ConfigModule,
        PassportModule.register({ defaultStrategy: 'jwt' }),
        JwtModule.registerAsync({
            inject: [ConfigService],
            useFactory: async (configService: ConfigService) => ({
                secretOrPrivateKey: config.jwtSecret,
                type: configService.dbType as any,
                host: configService.dbHost,
                port: configService.dbPort,
                username: configService.dbUsername,
                password: configService.dbPassword,
                database: configService.dbName,
                entities: ['./src/data/entities/*.ts'],
                signOptions: {
                    expiresIn: config.expiresIn,
                },
            }),
        }),

    ],
    providers: [AuthService, JwtStrategy],
    controllers: [AuthController],
})
export class AuthModule { }

Result

Nest can't resolve dependencies of the JWT_MODULE_OPTIONS (?). Please make sure that the argument at index [0] is available in the JwtModule context. +52ms

Environment


Nest version: 6.3.0
JWT version: 6.0.0 (6.1.1 same problem)
 
For Tooling issues:
- Node version: 10.12.0
- Platform:  Windows 10

Others:

How to register `JwtModule` with secret globally?

Currently I have to call JwtModule every where, how could I register it once and I could use JwtService every where?

@Module({
  providers: [],
  exports: [JwtModule],
  imports: [
    JwtModule.register({
      secret: process.env.SECRET
    })
  ],
})

registerAsync injection doesn't seem to be working

I'm submitting a...


[ ] Regression 
[ x ] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.

Current behavior

Nest is unable to resolve dependencies in registerAsync.

Expected behavior

Dependencies are resolved.

Minimal reproduction of the problem with instructions

@Module({
  imports: [
    DatabaseModule,
    EnvironmentModule,
    JwtModule.registerAsync({
      useFactory: function (environment: EnvironmentService) {
        return {
          secretOrPrivateKey: environment.getVariable('JWT_SECRET'),
          signOptions: {
            expiresIn: 3600,
          },
        };
      },
      inject: [EnvironmentService],
    }),
  ],
  providers: [
    AuthService,
    JwtStrategy,
  ],
})
export class AuthModule { }

Result

Error: Nest can't resolve dependencies of the JWT_MODULE_OPTIONS (?). Please make sure that the argument at index [0] is available in the current context.
    at Injector.lookupComponentInExports

I originally had useFactory set to a lambda, but switched to a function thinking maybe that had something with the error, but that didn't help.

I also tried useClass hoping maybe that'd resolve it, but got the same injector issues there.

Any ideas?

Environment


@nestjs/core: 5.3.4
@nestjs/jwt: 0.3.0


 
For Tooling issues:
- Node version: v8.12.0
- Platform:  Mac

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

Detected dependencies

circleci
.circleci/config.yml
  • cimg/node 21.6
  • cimg/node 21.6
npm
package.json
  • @types/jsonwebtoken 9.0.5
  • jsonwebtoken 9.0.2
  • @commitlint/cli 19.2.1
  • @commitlint/config-angular 19.1.0
  • @nestjs/common 10.3.5
  • @nestjs/core 10.3.5
  • @nestjs/testing 10.3.5
  • @types/jest 29.5.12
  • @types/node 20.11.30
  • @typescript-eslint/eslint-plugin 7.3.1
  • @typescript-eslint/parser 7.3.1
  • eslint 8.57.0
  • eslint-config-prettier 9.1.0
  • eslint-plugin-import 2.29.1
  • husky 9.0.11
  • jest 29.7.0
  • lint-staged 15.2.2
  • prettier 3.2.5
  • reflect-metadata 0.2.1
  • release-it 17.1.1
  • rxjs 7.8.1
  • ts-jest 29.1.2
  • typescript 5.4.3
  • @nestjs/common ^8.0.0 || ^9.0.0 || ^10.0.0

  • Check this box to trigger a request for Renovate to run again on this repository

Can't configure JWT following documentation

I'm submitting a...


[ ] Regression 
[x] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.

Current behavior

I am following the documentation present here
https://docs.nestjs.com/techniques/authentication#jwt-functionality
To have faster support I have created a git repository with the problem
https://github.com/Sano123456/nestjs-jwt

First Problem:

in AuthModule if I do as described in documentation and just import UserModule, it return me error of circular dependency between UserModule and AuthModule

@Module({
  imports:[
    UsersModule,
    PassportModule
  ],
  providers: [AuthService],
  controllers: [AuthController],
  exports:[AuthService, LocalStrategy]
})
export class AuthModule {}
 
[ExceptionHandler] Nest cannot create the AuthModule instance.
The module at index [0] of the AuthModule "imports" array is undefined.

Potential causes:
- A circular dependency between modules. Use forwardRef() to avoid it. Read more: https://docs.nestjs.com/fundamentals/circular-dependency
- The module at index [0] is of type "undefined". Check your import statements and the type of the module.

Scope [AppModule -> UsersModule] +6ms

Possibile solution in imports array of AuthModule instead of UserModule put forwardRef(() => UsersModule),
this actually remove the error but not sure if this is the right way

Second problem:

it says that can't find LocalStrategy class even if it's present and declared in AuthModule

[ExceptionHandler] Nest cannot export a provider/module that is not a part of the currently processed module (AuthModule). Please verify whether the exported LocalStrategy is available in this particular context.

Possible Solutions:
- Is LocalStrategy part of the relevant providers/imports within AuthModule?

Possibile solution right now I don't have any solution, I just remove it to understand what is the problem

Third problem problem:

after removing LocalStrategy,

[ExceptionHandler] Nest can't resolve dependencies of the AuthService (?). Please make sure that the argument dependency at index [0] is available in the AuthModule context.

Potential solutions:
- If dependency is a provider, is it part of the current AuthModule?
- If dependency is exported from a separate @Module, is that module imported within AuthModule?
  @Module({
    imports: [ /* the Module containing dependency */ ]
  })
 +1ms
Error: Nest can't resolve dependencies of the AuthService (?). Please make sure that the argument dependency at index [0] is available in the AuthModule context.

Expected behavior

to be configured as described

Minimal reproduction of the problem with instructions

https://github.com/Sano123456/nestjs-jwt

What is the motivation / use case for changing the behavior?

Environment



    nest -v -> 7.4.1

 
For Tooling issues:
- Node version:  v10.15.2
- npm version: 6.14.6
- Platform:  any

Others:

Generate 2 tokens with different exp time

I'm trying to generate 2 tokens: authorization token and refresh token.
These tokens usually have different validity time.
I can make a PR to add the options object in jwtService.sign, jwtService.verify, in order to override the existing JWT_MODULE_OPTIONS if another options are provided when calling the methods.
This way we can generate an authorization token for 1 minute and a refresh token for let's say 8h.

I'm submitting a...


[ ] Regression 
[ ] Bug report
[x] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.

Current behavior

In the current implementation you can generate tokens with the same validity time.
Authorization token and refresh token would have the same validity time and this defies the whole purpose of this auth mechanism.

Expected behavior

Being able to generate tokens with different validity time.

Minimal reproduction of the problem with instructions

What is the motivation / use case for changing the behavior?

Generate tokens with different validity time.

Environment


Nest version: 5.2.1

 
For Tooling issues:
- Node version: 10.11.0  
- Platform:  Mac

Others:

Update `@types/jsonwebtoken` to ^9.0.0

Did you read the migration guide?

  • I have read the whole migration guide

Is there an existing issue that is already proposing this?

  • I have searched the existing issues

Potential Commit/PR that introduced the regression

No response

Versions

9.0.0 -> 10.0.1

Describe the regression

Although the library jsonwebtoken is upgraded to version 9, the type declaration library @types/jsonwebtoken is still on 8.5.9.

Minimum reproduction code

@Module({
  imports: [
    JwtModule.registerAsync({
      useFactory () {
        return {
          secret: SECRET,
          // allowInsecureSizes is not in the `@types/jsonwebtoken` type declaration file.
          signOptions: { algorithm: 'HS256', allowInsecureKeySizes: true },
        };
      },
    }),
  ]
})

Expected behavior

allowInsecureKeySizes should be autocompleted in jwt.SignOptions type.

Other

No response

Documentation

I'm submitting a...


[ ] Regression 
[ ] Bug report
[ ] Feature request
[x] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.

Current behavior

Documentation on how to use this lib, is made for people who know NestJS very much. I simply don't know how to use it.
I am working on my project, and I am thinking about security

Expected behavior

More detailed examples geared toward NestJS beginners. Or at least an example folder inside the repo would also do the trick.

Modify unauthorized exception

I'm submitting a...


[ ] Regression
[ ] Bug report
[ ] Feature request
[x] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.

Expected behavior

It would be interesting to add documentation/feature to be able to modify the Unauthorized exception when jwt is invalid, has expired...

Tests are written with numerous gross mistakes

Is there an existing issue for this?

  • I have searched the existing issues

Current behavior

Tests are written with numerous gross mistakes. For example:

  1. In this code and all async tests with .resolves. / .rejects. syntax:

it('signing (async) should use SIGN option function', async () => {
expect(jwtService.signAsync('random')).resolves.toBe(
config.secretOrKeyProvider(JwtSecretRequestType.SIGN)
);
});

You need to put await before expect. See docs for Testing Asynchronous Code.

  1. After that, the tests start to crash with a timeout. This is because the wrong configuration of jest spy. As far as I understand, jest spy is not used at all.

  2. If you remove jest spy, the tests begin to fail due to incorrect expectations. For example sign() returns token, but here expected secret:

it('signing should use secret key', async () => {
expect(await jwtService.sign('random')).toBe(config.secret);
});

  1. And so on...

Minimum reproduction code

No response

Steps to reproduce

No response

Expected behavior

Tests must be written accurately and correctly.

Package version

8.0.0

NestJS version

No response

Node.js version

No response

In which operating systems have you tested?

  • macOS
  • Windows
  • Linux

Other

No response

JwtModule options not getting up (neither register nor registerAsync working)

I'm submitting a...


[ ] Regression 
[x] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.

Current behavior

I'm trying to set JwtModule options but those options are not getting loaded.
I'v tried both methods register() and registerAsync(), but none is working.

Expected behavior

I expect that the options passed to JwtModule.register() and JwtModule.registerAsync() methods get loaded.

Minimal reproduction of the problem with instructions

I've followed the instructions of https://docs.nestjs.com/techniques/authentication.

Then I've created an access token using RS265 algorithm. When I try to make a call to a guarded endpoint I'm getting the following error:

JsonWebTokenError: invalid algorithm
    at /var/www/html/visitown-api/node_modules/jsonwebtoken/verify.js:121:19
    at getSecret (/var/www/html/visitown-api/node_modules/jsonwebtoken/verify.js:90:14)
    at Object.module.exports [as verify] (/var/www/html/visitown-api/node_modules/jsonwebtoken/verify.js:94:10)
    at Function.module.exports [as JwtVerifier] (/var/www/html/visitown-api/node_modules/passport-jwt/lib/verify_jwt.js:4:16)
    at /var/www/html/visitown-api/node_modules/passport-jwt/lib/strategy.js:104:25
    at JwtStrategy._secretOrKeyProvider (/var/www/html/visitown-api/node_modules/passport-jwt/lib/strategy.js:40:13)
    at JwtStrategy.authenticate (/var/www/html/visitown-api/node_modules/passport-jwt/lib/strategy.js:99:10)
    at attempt (/var/www/html/visitown-api/node_modules/passport/lib/middleware/authenticate.js:366:16)
    at authenticate (/var/www/html/visitown-api/node_modules/passport/lib/middleware/authenticate.js:367:7)
    at /var/www/html/visitown-api/node_modules/@nestjs/passport/dist/auth.guard.js:87:3

Just for debugging reasons, I've edited node_modules/jsonwebtoken/verify.js and placed a console.log() just before line 129, to print options value. The result was:

{
  audience: undefined,
  issuer: undefined,
  algorithms: [ 'HS256', 'HS384', 'HS512' ],
  ignoreExpiration: false
}

Even calling JwtModule.register() with fixed values, the options value in verify.js file doesn't change:

JwtModule.register({
      signOptions: { mutatePayload: false, noTimestamp: false },
      secret: 'superSecret',
      verifyOptions: {
        algorithms: [
          'HS256', 'HS384',
          'HS512', 'RS256',
          'RS384', 'RS512',
          'ES256', 'ES384',
          'ES512', 'PS256',
          'PS384', 'PS512',
          'none'
        ],
        complete: false,
        ignoreExpiration: false,
        ignoreNotBefore: false
      }
    }),

What is the motivation / use case for changing the behavior?

I need to handle JWT generated with RS256 algotithm

Environment


@nest/core: 7.3.2
@nest/jwt: 7.1.0
passport: 0.4.1
passport-jwt: 4.0.0
 
Node version: 12.18.2

jwt blacklist feature

I'm submitting a...


[ ] Regression 
[ ] Bug report
[x] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.

Current behavior

N/A

Expected behavior

Hello, nestjs team there is a possibility to add an in-memory or db jwt blacklist feature?

Cannot resolve dependencies of module/service

I'm submitting a...

[x] Regression
[x] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.

Current behavior

Totally broken, neither register or registerAsync works.
Can't seem to resolve JWT_MODULE_OPTIONS nor the dependencies in registerAsync if that is used.

Error: Nest can't resolve dependencies of the JwtService (?). Please make sure that the argument at index [0] is available in the JwtModule context.

Expected behavior

Resolve JWT_MODULE_OPTIONS.

Minimal reproduction of the problem with instructions

JwtModule.register({
  secretOrPrivateKey: process.env.APP_SECRET,
}),

Environment

Nest version: 5.4.0
 
For Tooling issues:
- Node version: 10.9.0
- Platform: WSL

add support for json web key sets

I'm submitting a...


[ ] Regression 
[ ] Bug report
[x] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.

Current behavior

jwtService.verify calls jwt.verify synchronously.

Expected behavior

If jwt.verify is called asynchronous, secretOrPublicKey can be a function that can fetch the secret or public key.

Minimal reproduction of the problem with instructions

I'll submit my PR shortly.

What is the motivation / use case for changing the behavior?

I would like to add support for json web key sets.

sign function dosent take secret registred in module

Is there an existing issue for this?

  • I have searched the existing issues

Current behavior

After using registerAsync or register at module level with secret, that seem to be undefined at sign methode.

Minimum reproduction code

https://gist.github.com/omarberrami/d6bf3eefee8e967b836a44b10e2679ff , https://gist.github.com/omarberrami/f91140240bac674e03fdde364a217875

Steps to reproduce

follow nest documentation to implement jwt, and sign function wil trigger an error

Expected behavior

the secred passed to module need to be availeble at signe methode without ovverding it againat signe methode level

Package version

9.0.0

NestJS version

9.0.1

Node.js version

12.22.10

In which operating systems have you tested?

  • macOS
  • Windows
  • Linux

Other

secretOrPrivateKey must have a value at Object.module.exports [as sign] (/Users/cloudeco/Documents/bee-in/api-app-itiforums/node_modules/jsonwebtoken/sign.js:107:20) at JwtService.sign (/Users/cloudeco/Documents/bee-in/api-app-itiforums/node_modules/@nestjs/jwt/dist/jwt.service.js:29:20) at AuthService.loginWithCredentials (/Users/cloudeco/Documents/bee-in/api-app-itiforums/src/auth/auth.service.ts:45:44) at processTicksAndRejections (internal/process/task_queues.js:97:5) at AuthController.authByEmailAndPass (/Users/cloudeco/Documents/bee-in/api-app-itiforums/src/auth/auth.controller.ts:11:12) at /Users/cloudeco/Documents/bee-in/api-app-itiforums/node_modules/@nestjs/core/router/router-execution-context.js:46:28 at /Users/cloudeco/Documents/bee-in/api-app-itiforums/node_modules/@nestjs/core/router/router-proxy.js:9:17

Can not import JwtService, JwtModule after installed

Is there an existing issue for this?

  • I have searched the existing issues

Current behavior

Hello, i follow https://docs.nestjs.com/security/authentication to practise for jwt. i see "@nestjs/jwt": "github:nestjs/jwt" on my "package.json" but i can not import JwtService, JwtModule. It show me errors:

Module '"@nestjs/jwt"' has no exported member 'JwtModule'
and
Module '"@nestjs/jwt"' has no exported member 'JwtService'

npm: 6.14.13
node: v14.17.2
"@nestjs/cli": "^8.0.0"

what i should do?

Minimum reproduction code

https://docs.nestjs.com/security/authentication

Steps to reproduce

npm install --save @nestjs/jwt passport-jwt
npm install --save-dev @types/passport-jwt

Expected behavior

import { JwtModule, JwtService } from "@nestjs/jwt";

Package version

8.0.0.

NestJS version

8.0.0

Node.js version

14.17.2

In which operating systems have you tested?

  • macOS
  • Windows
  • Linux

Other

No response

async secretOrKeyProvider

I'm submitting a...


[ ] Regression 
[ ] Bug report
[x] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.

Current behavior

secretOrKeyProvider must return the key synchronously

Expected behavior

If we are using jwks, we need to get this key from a http endpoint. Therefore, secretOrKeyProvider must support promises

What is the motivation / use case for changing the behavior?

Auth0 exposes the public keys via JWKS (https://github.com/auth0/node-jwks-rsa/tree/master/examples/express-demo)

Environment


Nest version: 7.0.0
 
For Tooling issues:
- Node version: 12
- Platform:  Mac

method for dynamic secret signing rather than globally configured secret

I'm submitting a...

[ ] Regression
[ ] Bug report
[x] Feature request
[x] Documentation issue or request
[ ] Support request

Current behavior

Currently there is no way to sign the token dynamically. (see user.secret comment). So far based on the documentation I can't seem to find a good solution. Maybe more docs are missing? In case somebody asks the same question I have created a SO post:

https://stackoverflow.com/questions/55354102/using-nestjs-jwt-signing-with-dynamic-user-related-secret/55354309#55354309

@Injectable()
export class AuthService {
  public constructor(private readonly jwtService: JwtService, private readonly userService: UserService) {}

  public async createToken(email: string): Promise<JwtReply> {
    const expiresIn = 60 * 60 * 24;
    const user = await this.userService.user({ where: { email } });
    const accessToken = await this.jwtService.signAsync({ email: user.email }, /* user.secret ,*/ { expiresIn });

    return {
      accessToken,
      expiresIn,
    };
  }
}

Expected behavior

Option 1:

Sign should work similar to jwt-token libraries sign method. Re-add second parameter as secret key rather than options.

Option 2:

Add a secretOrPrivateKeyProvider similar to PassportStrategy of @nestjs/passport

JwtModule.register({
      secretOrPrivateKeyProvider: userService.provideSecret,
      signOptions: {
        expiresIn: 3600,
      },
    })

Minimal reproduction of the problem with instructions

See first code example above

What is the motivation / use case for changing the behavior?

I'm new to nestjs and cautious about security. This might be opinionated and I apologise if this is the case here. For security purposes rather than relying on a single secret, if stolen, the whole infrastructure is compromised. When stealing a single secret a single user is compromised and the damage lowered when using dynamic secret signing. "stealing" may sound vague, but I hope it simplifies what I mean in general.

How to invalidate a token?

Is there an existing issue for this?

  • I have searched the existing issues

Current behavior

How to invalidate a token based on this example?
https://github.com/nestjs/nest/tree/master/sample/19-auth-jwt

I reissue the token when requesting logout API, the expiration time of the original token remains unchanged, and I can still use the old token to request data. What should I do?

image

image

image

image

Minimum reproduction code

https://github.com/wjw-gavin/nest-study

Steps to reproduce

No response

Expected behavior

none

Package version

10

NestJS version

9

Node.js version

18

In which operating systems have you tested?

  • macOS
  • Windows
  • Linux

Other

No response

nest can't resolve dependencies of AuthService

I'm submitting a...


[ ] Regression 
[x] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.

Current behavior

When compiling the nestjs project, I'm getting the

[ExceptionHandler] Nest can't resolve dependencies of the AuthService (UsersService, ?). Please make sure that the argument at index [1] is available in the AppModule context. +2ms
Error: Nest can't resolve dependencies of the AuthService (UsersService, ?). Please make sure that the argument at index [1] is available in the AppModule context.

error.

Expected behavior

It should be working.

Minimal reproduction of the problem with instructions

My auth.module.ts:

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { UsersModule } from '../users/users.module';
import { JwtModule } from '@nestjs/jwt';
import { PassportModule } from '@nestjs/passport';
import { JwtStrategy } from './jwt.strategy';

@Module({
  imports: [
    UsersModule,
    PassportModule.register({ defaultStrategy: 'jwt' }),
    JwtModule.register({
      secret: 'secretKey',
      signOptions: {
        expiresIn: 86400,
      },
    }),
  ],
  providers: [AuthService, JwtStrategy],
  exports: [AuthService],
})
export class AuthModule {}

My user.module.ts:

import { Module } from '@nestjs/common';
import { UsersService } from './users.service';
import { UsersController } from './users.controller';
import { TypeOrmModule } from '@nestjs/typeorm';
import { UserRepository } from './user.repository';

@Module({
  imports: [TypeOrmModule.forFeature([UserRepository])],
  providers: [UsersService],
  controllers: [UsersController],
  exports: [UsersService],
})
export class UsersModule {}

My auth.service.ts:

@Injectable()
export class AuthService {
  constructor(private readonly usersService: UsersService, private readonly jwtService: JwtService) {}

  async validateUser(userId: string, pass: string): Promise<any> {
    const user = await this.usersService.findUserById(userId);
    if (user && user.password === pass) {
      const { password, ...result } = user;
      return result;
    }
    return null;
  }

  async login(user: User) {
    const payload: JwtPayload = { id: user.user_id };
    return {
      access_token: this.jwtService.sign(payload),
    };
  }
}

My app.module.ts:

import { Module } from '@nestjs/common';
import { typeOrmConfig } from './config/typeorm.config';
import { TypeOrmModule } from '@nestjs/typeorm';
import { ProductsModule } from './products/products.module';
import { UsersModule } from './users/users.module';
import { AuthService } from './auth/auth.service';
import { AuthModule } from './auth/auth.module';

@Module({
  imports: [TypeOrmModule.forRoot(typeOrmConfig), ProductsModule, UsersModule, AuthModule],
  providers: [AuthService],
})
export class AppModule {}

What is the motivation / use case for changing the behavior?

I've done everything what the tutorial is saying, I couldn't find a place in a code with an obvious error.
From my understanding the error is talking about this exact place in the code:

export class AuthService {
  constructor(private readonly usersService: UsersService, private readonly jwtService: JwtService) {}

and so apparently it can't find JwtService, but clearly, I'm loading it in auth.module.ts, as JwtModule. Not sure what else could be wrong here.

Also what is worth mentioning, everything worked correctly up untill I've added jwtService in the AuthService constructor.

Environment


Nest version: 6.4.1
 
For Tooling issues:
- Node version: Yarn 1.16.0
- OS: Mac 

Revoked tokens

I'm submitting a...


[ ] Regression 
[ ] Bug report
[x] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.

Current behavior

Unable to Revoked tokens.

Expected behavior

Revoked tokens, like :https://github.com/auth0/express-jwt#revoked-tokens

Minimal reproduction of the problem with instructions

Revoked tokens

It is possible that some tokens will need to be revoked so they cannot be used any longer. You can provide a function as the isRevoked option. The signature of the function is function(req, payload, done):

  • req (Object) - The express request object.
  • payload (Object) - An object with the JWT claims.
  • done (Function) - A function with signature function(err, revoked) to be invoked once the check to see if the token is revoked or not is complete.
    • err (Any) - The error that occurred.
    • revoked (Boolean) - true if the JWT is revoked, false otherwise.

For example, if the (iss, jti) claim pair is used to identify a JWT:

var jwt = require('express-jwt');
var data = require('./data');
var utilities = require('./utilities');

var isRevokedCallback = function(req, payload, done){
  var issuer = payload.iss;
  var tokenId = payload.jti;

  data.getRevokedToken(issuer, tokenId, function(err, token){
    if (err) { return done(err); }
    return done(null, !!token);
  });
};

app.get('/protected',
  jwt({secret: 'shhhhhhared-secret',
    isRevoked: isRevokedCallback}),
  function(req, res) {
    if (!req.user.admin) return res.sendStatus(401);
    res.sendStatus(200);
  });

What is the motivation / use case for changing the behavior?

When the token is leaked, we need to undo the token.

Wrong dependency @types/jsonwebtoken

Is there an existing issue for this?

  • I have searched the existing issues

Current behavior

When using npm install --omit=dev there are @types installed for jsonwebtoken and node.

Minimum reproduction code

https://github.com/mvandenbrink/nestjs-jwt-issue

Steps to reproduce

  1. nest new nest-jwt-issue --strict
  2. cd .\nest-jwt-issue\
  3. npm install --save @nestjs/passport passport passport-local @nestjs/jwt passport-jwt
  4. npm install --save-dev @types/passport-local @types/passport-jwt
  5. rmdir -R node_modules
  6. npm install --omit=dev
  7. npm explain @types/node
@types/[email protected]
node_modules/@types/node
  dev @types/node@"^16.0.0" from the root project
  @types/node@"*" from @types/[email protected]
  node_modules/@types/jsonwebtoken
    @types/jsonwebtoken@"8.5.8" from @nestjs/[email protected]
    node_modules/@nestjs/jwt
      @nestjs/jwt@"^9.0.0" from the root project

Expected behavior

Empty @types folder

Package version

9.0.0

NestJS version

9.1.2

Node.js version

16.16.0

In which operating systems have you tested?

  • macOS
  • Windows
  • Linux

Other

No response

Typescript checker not working on "JwtModule.registerAsync" when using "useFactory"

I'm submitting a...


[ ] Regression 
[x] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.

Current behavior

Type checker not working on JwtModule.registerAsync when using useFactory funcition.

image

It's wired because I check the type and It is correct.

image

Also there is any issue on that file.

Expected behavior

Minimal reproduction of the problem with instructions

What is the motivation / use case for changing the behavior?

Environment


Nest version: X.Y.Z

 
For Tooling issues:
- Node version: XX  
- Platform:  

Others:

Also I know this is not the place for this but...
Nest such is a really great project. I love it ❤ I would like to contribute on anything if posible.
Time ago I wanted to create some framework in typescript in witch you could return promises and throw exceptions instead of using the res object. But then I check this project and It's just like my dream come true.

So if there´s anything I can do please tell me. From pull requests to docs contribution 👍

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.