I'm in the process of developing a middleware to retrieve a member entity and attach it to the request object. However, I require the userId from the user object obtained through JwtAuthGuard, and unfortunately the guards are executed after middlewares.
One solution I am considering is creating an interceptor instead of a middleware to handle this task or incorporating the authentication directly into the middleware logic.
Below is the middleware code I have been working on:
@Injectable()
export class SpaceMemberMiddleware implements NestMiddleware {
constructor(private readonly membersService: MembersService) {}
async use(req: any, res: any, next: () => void) {
const user: User = req.user;
const member: Member = await this.membersService.findByUserId(user.userId);
if (!member) throw new BadRequestException();
req.member = member;
next();
}
}
This is followed by my AuthGuard:
@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {
constructor(private reflector: Reflector) {
super();
}
canActivate(
context: ExecutionContext,
): boolean | Promise<boolean> | Observable<boolean> {
const isPublic = this.reflector.getAllAndOverride<boolean>(IS_PUBLIC_KEY, [
context.getHandler(),
context.getClass(),
]);
return isPublic || super.canActivate(context);
}
}
Lastly, here is my Strategy implementation:
@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
constructor(private readonly usersService: UsersService) {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
ignoreExpiration: false,
});
}
async validate(payload: { username: string }): Promise<User> {
const user: User = await this.usersService.findOneByCognitoId(
payload.username,
);
if (!user) throw new UnauthorizedException();
return user;
}
}
I would greatly appreciate any recommendations or suggestions on how to proceed with this setup. Thank you for your understanding, and please excuse any language errors as English is not my first language. Thank you.