5

Hi I'm trying to build a NestJS API and wanna learn the best practices to do it.

So I was wondering why the documentation of Nest JS

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

is providing an example of authentication with coupling passport-local and passport-jwt strategies?

Couldn't it be possible to just use the passport-jwt?

If the answer is, yes but it's not a good practice, could you provide explanations.

And if the answer is yes and it's the best practice, do you have any idea why they put an example that is not using best practices on such an important subject like authentication?

2 Answers2

2

If I remember well the documentation, from the time I did my own authentication with Nest, the jwt and the local strategies are 2 ways to validate your users access but can be used in complementary.

The local strategy allow your server to validate the user with its username and password. So it will work well for a login endpoint, where the user fill the login form of your app.

Using this first step, you can use the jwt token api to create a token that will identify the user. You can set for example this token in a cookie, to be able to access it on your server when the user will make other requests.

Now, the jwt strategy will be perfect to validate the user by checking its datas and its signature in the token.

So to answer your question, you can of course use only one of this 2 strategies, but you will need to implement what they do on your own. For example, the local strategy will be really easy to imitate by a simple endpoint in a resolver or a controller which check user information (username and password) in your DB, and set a cookie if succeed or respond an unauthorized if it failed

Hope what I say make sens !

yolan PIBRAC
  • 153
  • 1
  • 7
  • 1
    Okay, makes sense, so If I understood well, the local strategy is used only to handle the login/register endpoints, and will never be used on other endpoints, because It's the role of the JWT strategy right? Btw you should edit your answer, best practice is to store JWT on client local storage then attach it as Bearer to Authorization header. – Oscar Rénier Oct 02 '21 at 21:46
  • 1
    Yes exactly ! About the best practice to store JWT, local storage + Authorization header work well but is vulnarable to XSS attack. To avoid XSS attacks, it is better to use a cookie with the HttpOnly flag. – yolan PIBRAC Oct 17 '21 at 21:07
1

Couldn't it be possible to just use the passport-jwt?

Yes, is possible use login controller without passport-local. Passport-local only receibe two params (username and password) and you need implement validation, the returned value is pass how "user" propertie in Query object. You can omit passport-local, implement the login controller with a loginDto in the @Body and validate credentials, are the same. Example:

@Post('/auth/login')
async login(@Body() loginUserDto: LoginUserDto){
  user = validation.....
  if !(user) throw new UnauthorizedException();
  return generateJwt(user);
}

where LoginUserDto can be

export class LoginUserDto {
  @ApiProperty()
  @IsString()
  @IsLowercase()
  @IsNotEmpty()
  username: string;

  @ApiProperty()
  @IsNotEmpty()
  @IsString()
  password: string;
}

passport-jwt is only for validate the jwtoken sent by the user to privates routes of resources (endpoints).

The answer to the question if it is good practice, i don't know, for me is the same.