here's my study project codes. im trying to nestjs+jwt+passport. however, no matter what method i use, i get a 401 Unauthorized error. i cant even access the validate function, and when i try to console.log, it doesnt appear... im sorry to ask you this question, and thanks for everybody's help
auth.controller.ts
import { Body, Controller, Get, Post, Req, UnauthorizedException, UseGuards } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { LoginDTO } from 'src/user/login.dto';
import { UserService } from 'src/user/user.service';
import { AuthGuard } from './auth.guard';
@Controller()
export class AuthController {
constructor(
private readonly userService: UserService,
private readonly jwtService: JwtService
) {}
@Post('/signin')
async signin(@Body() loginDTO: LoginDTO) {
const user = await this.userService.findByLogin(loginDTO);
if (!user) {
throw new UnauthorizedException('check again');
}
const accessToken = this.jwtService.sign({ email: loginDTO.email });
return { accessToken: accessToken };
}
@UseGuards(AuthGuard)
@Get('/test')
async getProfile(@Req() req) {
const user = req.user;
return user;
}
}
auth.passport.jwt.ts
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { ExtractJwt, Strategy } from 'passport-jwt';
import { UserService } from 'src/user/user.service';
@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy, 'jwt') {
constructor(private userService: UserService) {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
ignoreExpiration: true,
secretOrKey: `${process.env.AUTH_SECRET_KEY}`
});
}
async validate(payload: { email: string }) {
const { email } = payload;
const user = await this.userService.findByEmail(email);
if (!user) {
throw new UnauthorizedException({ message: 'null' });
}
return user;
}
}
auth.module.ts
import { Module } from '@nestjs/common';
import { JwtModule } from '@nestjs/jwt';
import { AuthController } from './auth.controller';
import { UserModule } from 'src/user/user.module';
import { PassportModule } from '@nestjs/passport';
import { JwtStrategy } from './auth.passport.jwt';
@Module({
imports: [
JwtModule.register({
secret: `${process.env.AUTH_SECRET_KEY}`
}),
UserModule,
PassportModule
],
controllers: [AuthController],
providers: [JwtStrategy]
})
export class AuthModule {}
auth.guard.ts
import { ExecutionContext, Injectable } from '@nestjs/common';
import { AuthGuard as NestAuthGuard } from '@nestjs/passport';
@Injectable()
export class AuthGuard extends NestAuthGuard('jwt') {
canActivate(context: ExecutionContext) {
return super.canActivate(context);
}
}
I've tried using AuthGuard() from @nestjs/passport instead of AuthGuard in the controller's @UseGuards(AuthGuard) section, but the same error occurs.
the problem comes from the fact that in your authControler in the getProfil method, you retrieve the user from the request without specifying its type. replace :
with:
import Request like:
Here are some tips to adopt to properly organize your code: Replace :
with in your authModule, because you have already specified this in the strategy:
You don't need to create the AuthGuard class, because nestjs through passport already integrates this. In your controler import the AuthGuard from:
when you also generate an accessToken, you must always specify a duration and secret:
finally replace replace:
with
ignoreExpiration: false,If this solved your problem, please mark my answer as the solution. good continuation