Consider that I have two routes in NestJS called “signUp” and “validate-code”, both of which are inside the SignupModule. For the signUp route, I return an accessToken using JWT. Here’s the code:
const payload = {
mobileNumber: user.mobileNumber
};
return [
{...userData,accessToken: this.jwtService.sign(payload),}
];
After sending the mobile number as a request using Postman to the server, everything works fine and I get an accessToken.
Now, I want to use this accessToken to authorize the validate-code route and check if the user has already registered and their information exists in the database. I have to send the mobileNumber and code to this route along with the accessToken that I received previously through the signUp route. I set the accessToken in Postman as Bearer, but it gives me the following message:
{
"statusCode": 401,
"message": "Unauthorized"
}
The classes written for JWT are as follows:
import {Injectable} from "@nestjs/common";
import {AuthGuard} from "@nestjs/passport";
@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {
}
//---------------------------------------------------------------
import {AuthGuard} from '@nestjs/passport';
import {Injectable} from "@nestjs/common";
@Injectable()
export class LocalAuthGuard extends AuthGuard('local') {
}
//---------------------------------------------------------------
import {PassportStrategy} from "@nestjs/passport";
import {ExtractJwt} from "passport-jwt";
import {Strategy} from "passport-local";
export class JwtStrategy extends PassportStrategy(Strategy, 'jwt') {
constructor() {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
secretOrKey: `${process.env.JWT_SECRET}`,
ignoreExpiration: false,
passReqToCallback: true,
});
}
async validate(payload: any) {
return {
mobileNumber: payload.mobileNumber
};
}
}
//---------------------------------------------------------------
import {Injectable, UnauthroziedException} from "@nestjs/common";
import {PassportStrategy} from "@nestjs/passport";
import {Strategy} from 'passport-local';
import {SignupService} from "./signup.service";
@Injectable()
export class LocalStrategy extends PassportStrategy(Strategy) {
constructor(private readonly signupService: SignupService) {
super();
}
async validate(mobileNumber: string) {
const user = await this.signupService.validateUser(mobileNumber);
if (!user) {
throw new UnauthroziedException();
}
return user;
}
}
The signUp route in the SignupController:
@Post('signup')
async signUp(@Body() dto: SignupDto, @Res() res: Response):Promise<Response<any,Record<string, any>>> {
const result = await this.authService.signUp(dto.mobileNumber);
return res.status(result ? HttpStatus.CREATED : HttpStatus.INTERNAL_SERVER_ERROR).json({'message':result});
}
The validate-code route in the SignupController:
@UseGuards(LocalAuthGuard)
@Post('validate-code')
async validateCode(@Body() dto:VerifyCodeDto,@Res() res:Response):Promise<Response<any,Record<string, any>>>{
const [statusCode,data] = await this.authService.verifyCode(dto);
return res.status(statusCode).json(data);
}
Finally, the SignupModule is implemented to use JWT and Passport:
@Module({
imports: [
JwtModule.register({
secret: `${process.env.JWT_SECRET}`,
signOptions: { expiresIn: '60s' },
}),
ThrottlerModule.forRoot(
{
ttl: 30,
limit: 6
}
),
PrismaModule,
ApiModule
],
controllers: [AuthController],
providers: [
JwtStrategy,
LocalStrategy,
SignupService,
{
provide: APP_GUARD,
useClass: ThrottlerGuard
}
]
})
export class SignupModule {
}
So, I have no problem with the signUp route and getting the accessToken, but I cannot use it for the validate-code route. What could be the problem?