Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Optional Authentication in nestjs

I want to know if there is a decorator that makes the req.user object available in a controller method, if the user is logged in (Authaurization header sent), if not then just let the req.user be null.

The AuthGuard decorator will return 401 if the user is not logged in, so it's not suitable for my case.

like image 484
KarimS Avatar asked Nov 11 '18 14:11

KarimS


People also ask

What is JWT token in NestJS?

JWT or JSON Web Token is an industry standard RFC 7519 method for representing claims securely between two parties. Passport is the most popular Node authentication library, well-known by the community and successfully used in many production application, NestJS has supported it outside the box with @nestjs/passport.

What is passport in NestJS?

Passport is the most popular node.js authentication library, well-known by the community and successfully used in many production applications. It's straightforward to integrate this library with a Nest application using the @nestjs/passport module.

How secure is NestJS?

NestJS follows mostly the same security rules as the Node. js server and Express. NestJS has an dedicated security section in its documentation that addresses these topics: Authentication.


1 Answers

There is no built-in decorator but you can easily create one yourself. See the example from the docs:

import { createParamDecorator } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';

export const User = createParamDecorator((data, req) => {
  return req.user;
});

Since the built-in AuthGuard throws an exception, you can create your own version and overwrite the request handler:

@Injectable()
export class MyAuthGuard extends AuthGuard('jwt') {

  handleRequest(err, user, info) {
    // no error is thrown if no user is found
    // You can use info for logging (e.g. token is expired etc.)
    // e.g.: if (info instanceof TokenExpiredError) ...
    return user;
  }

}

Make sure that you are not throwing errors in your JwtStrategy:

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor(private readonly authService: AuthService) {
    super({
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      secretOrKey: 'secretKey',
    });
  }

  async validate(payload) {
    const user = await this.authService.validateUser(payload);
    // in the docs an error is thrown if no user is found
    return user;
  }
}

Then you can use it in your Controller like this:

@Get()
@UseGuards(MyAuthGuard)
getUser(@User() user) {
  return {user};
}
like image 98
Kim Kern Avatar answered Sep 18 '22 11:09

Kim Kern