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.
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.
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.
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.
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};
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With