Reputation: 113
I'm trying to use jwt in nest following document
Everything is ok, but validate function is not working in jwt.strategy.ts
this is my jwt.strategy.ts:
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { ExtractJwt, Strategy } from 'passport-jwt';
import { AuthService } from './auth.service';
import { JwtPayload } from './interfaces/jwt-payload.interface';
@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
constructor(private readonly authService: AuthService) {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderWithScheme('JWT'),
secretOrKey: 'secretKey',
});
}
async validate(payload: JwtPayload) {
console.log(payload)
// const user = await this.authService.validateUser(payload);
// if (!user) {
// throw new UnauthorizedException();
// }
// return user;
}
}
auth.module.ts:
import { Module } from '@nestjs/common';
import { JwtModule } from '@nestjs/jwt';
import { PassportModule } from '@nestjs/passport';
import { AuthService } from './auth.service';
import { JwtStrategy } from './jwt.strategy';
@Module({
imports: [
PassportModule.register({ defaultStrategy: 'jwt' }),
JwtModule.register({
secretOrPrivateKey: 'secretKey',
signOptions: {
expiresIn: 3600,
},
}),
],
providers: [AuthService, JwtStrategy],
})
export class AuthModule {}
app.module.ts:
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { TypeOrmModule } from '@nestjs/typeorm';
import { UserModule } from './user/user.module';
import { GraphQLModule } from '@nestjs/graphql';
import { AuthModule } from './auth/auth.module';
@Module({
imports: [
TypeOrmModule.forRoot(),
GraphQLModule.forRoot({
typePaths: ['./**/*.graphql'],
}),
AuthModule,
UserModule,
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
When i request in postman, I don't got any log, It doesn't seem to enter this validate function.:
sorry, my English is bad, this is my first-time use stackoverflow, thanks for your help
Upvotes: 11
Views: 10210
Reputation: 2095
I would also add my scenario.
Case 1: JWT token is malformed
Basically, when your JWT token is malformed (don't confuse with not valid) the validate function would NOT call. In other words, when you debug token via jwt.io and it shows signature is not valid.
It appears from my side even if I was login in succesfully on local via
@auth0/auth0-angular
, I was not providing audience url(available on APIs section in auth0). The getting started docs was not mentioning this, so below is working code
// Angular side
AuthModule.forRoot({
domain: `${auth.domain}`,
clientId: 'client-id',
useRefreshTokens: true,
audience: `https://${auth.audience}/`
}),
Case 2: JWT token is not valid
In that case, I found out that URLs provided in JwtStrategy in NestJs, the URLs must be an exact match. So if you forget to add /
at the end of the URL, it would not pass AuthGuard
.
// NestJs side
export class JwtStrategy extends PassportStrategy(Strategy) {
constructor() {
super({
secretOrKeyProvider: passportJwtSecret({
cache: true,
rateLimit: true,
jwksRequestsPerMinute: 5,
jwksUri: `https://${auth.domain}/.well-known/jwks.json`,
}),
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
audience: `https://${auth.audience}/`,
issuer: `https://${auth.domain}}/`,
algorithms: ['RS256'],
});
}
public validate(payload: any): unknown {
return payload;
}
}
Upvotes: 1
Reputation: 60457
The validate
method of your JwtStrategy
will only be called when the token has been verified in terms of the encryption (corrrect key was used to sign it, in your case secretKey
) and it is not expired. Only after those two things have been checked, validate
is called with the payload. With it, you can then e.g. check if the user still exists. So the three steps are:
You can use the jwt debugger to manually check steps 1 and 2 for your token.
Upvotes: 14