I have a UseGuard
in my WebSocket. Actually, this guard is a JwtAuthGuard
that extends AuthGuard('jwt')
. The JwtAuthGuard
has a Strategy class called JwtStrategy
. In this class, I have a validate
method. In HTTP-based requests I return payload in this method. Then nestjs attach the payload to the req
. Here is my Strategy class:
@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
constructor(private authConfigService: AuthConfigService) {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
ignoreExpiration: false,
secretOrKey: authConfigService.JWT_SECRET,
});
}
async validate(payload: any) {
return payload;
}
}
I want to have access to context within validate
method in order to attach the payload to the WebSocket's body (or anything that I can have access to the payload). Any idea?
You don't need to make any modifications to your strategy class. Instead, you should modify your JwtAuthGuard
's getRequest
method (if you don't have one then you should make one) that returns an object that has a headers
proeprty that is an object with a authorization
property that is a string. Something like
@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {
getRequest(context: ExecutionContext) {
const ws = context.switchToWs().getClient(); // possibly `getData()` instead.
return {
headers: {
authorization: valueFromWs(ws),
}
}
}
}
You can also make this work across different context types by using an if/else
or a switch
statement and returning the correct object based on the contextType
from context.getType()
. Whatever is returned from this getRequest
method is where passport will end up attaching the user
property, so it may make sense to return the entire client with these extra values.