I want to create a NestJs app and want to have a middleware validating the token in the request object and a authentication guard validating the user in the token payload.
By splitting this I was hoping to have a clean separation. First my middleware
@Injectable()
export class TokenMiddleware implements NestMiddleware {
use(req: any, res: Response, next: NextFunction) {
try {
const headers: IncomingHttpHeaders = req.headers;
const authorization: string = headers.authorization;
const bearerToken: string[] = authorization.split(' ');
const token: string = bearerToken[1];
// !! Check if token was invalidated !!
req.token = token;
req.tokenPayload = verifyToken(token);
next();
} catch (error) {
throw new UnauthorizedException();
}
}
}
It only validates the token and extends the request object with the encoded token and its payload. My auth guard
@Injectable()
export class AuthenticationGuard implements CanActivate {
constructor(private readonly usersService: UsersService) {}
async canActivate(context: ExecutionContext): Promise<boolean> {
const request: any = context.switchToHttp().getRequest();
try {
const user: any = request.tokenPayload;
if (!user) {
throw new Error();
}
const findByIdDTO: FindByIdDTO = { id: user.id };
const existingUser: UserRO = await this.usersService.findById(findByIdDTO);
if (!existingUser) {
throw new Error();
}
// attach the user to the request object?
return true;
} catch (error) {
throw new UnauthorizedException();
}
}
}
This guard checks if the provided user in the tokenpayload is a valid one. If everything is fine, where should I attach the user to the request object? As far as I know the guard only checks if something is correct. But I don't want to keep all this logic in the token middleware. Where can I attach the database user to the request after finishing the validation in the auth guard?