Reputation: 754
I am trying to understand NestJS 01-cats-app. When trying a post request, I get a 403 error. I know that is due to the @Roles('admin')decorator. But how do I create a post request as an admin? I use postman btw.
Here is the example: https://github.com/nestjs/nest/tree/master/sample/01-cats-app
Upvotes: 1
Views: 2773
Reputation: 3968
Here, roles are being validated by Guards. So in this case, 'admin' role will be validated inside guards file.
import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
@Injectable()
export class RolesGuard implements CanActivate {
constructor(private reflector: Reflector) {}
canActivate(context: ExecutionContext): boolean {
const roles = this.reflector.get<string[]>('roles', context.getHandler());
if (!roles) {
return true;
}
const request = context.switchToHttp().getRequest();
const user = request.user;
return matchRoles(roles, user.roles);
}
}
In the above code, raw request is extracted from context and it has user object inside it which contains roles.
However, we need to inject user object into request using middleware or something like that.
For more information, you can read official docs for guards from nestjs
https://docs.nestjs.com/guards
async canActivate(context: ExecutionContext): Promise<boolean> {
const request = context.switchToHttp().getRequest() as Request & {
user: User;
};
const authorization = request.headers.authorization || '';
if (!authorization.trim().length) {
throw new UnauthorizedException();
}
const token = authorization.split(' ')[1];
if (!token) {
throw new UnauthorizedException();
}
let decoded: PayloadType | null = null;
try {
decoded = verify(
token,
process.env.ACCESS_SECRET || 'qwertyuiop',
) as PayloadType;
} catch (error) {
throw new BadRequestException(error.message);
}
const role = this.reflector.get<string[]>('roles', context.getHandler());
if (!role) {
return true;
}
const user = (await User.findOne(decoded.id, {
select: [
'tokenVersion',
'id',
'email',
'isPaidUser',
'firstName',
'lastName',
'profileUrl',
'roles',
],
})) as User;
if (!user) {
throw new NotFoundException('user not found');
}
if (user.tokenVersion !== decoded.tokenVersion) {
throw new BadRequestException('token invalid');
}
const hasRole = () =>
user.roles.some(role => !!roles.find(item => item === role));
if(!hasRole){
throw new UnauthorizedException();
}
request.user = serializeUser(user);
return true;
}
Upvotes: 1