I am a beginner in Nestjs When using JWTGuard in my user controller for all my CRUD operations it returns always 401 unauthorized error This is my JWT Strategy
import { PassportStrategy } from "@nestjs/passport";
import { JwtPayload } from "jsonwebtoken";
import { ExtractJwt, Strategy } from "passport-jwt";
export class JwtStrategy extends PassportStrategy(Strategy, 'jwt') {
constructor() {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
secretOrKey: `${process.env.SECRET}`,
ignoreExpiration: false,
});
}
async validate(payload: JwtPayload) {
console.log('JWT Strategy - Validate: ', payload);
return { user: payload.sub, username: payload.username }
}
}
This is my authService
import { Injectable } from '@nestjs/common';
import { UserService } from 'src/user/user.service';
import * as bcrypt from 'bcrypt'
import { User } from 'src/user/schemas/user_schema';
import { JwtService } from '@nestjs/jwt';
@Injectable()
export class AuthService {
constructor(
private readonly userService: UserService,
private jwtService: JwtService) { }
async validateUser(email: string, password: string) {
const user = await this.userService.findOneWithEmail(email)
if (user && await bcrypt.compare(password, user.password)) {
const { password, ...result } = user
return result;
}
return null;
}
async login(user: User) {
const payload = {
username: user.email,
sub: {
name: user.name
}
}
user.password = undefined
return {
...user,
accessToken: this.jwtService.sign(payload),
refreshToken: this.jwtService.sign(payload, { expiresIn: '1d' }),
}
}
async refreshToken(user: User) {
const payload = {
username: user.email,
sub: {
name: user.name,
},
};
return {
accessToken: this.jwtService.sign(payload),
};
}
}
This is my user controller
import { Controller, Get, Post, Body, Patch, Param, Delete, ValidationPipe, UsePipes, Res, Redirect, Request, UseGuards, Query } from '@nestjs/common';
import { UserService } from './user.service';
import { CreateUserDto } from './dto/create-user.dto';
import { UpdateUserDto } from './dto/update-user.dto';
import { JwtGuard } from 'src/auth/guards/jwt-auth.guard';
import { AuthService } from 'src/auth/auth.service';
import { Query as ExpressQuery } from 'express-serve-static-core';
@Controller('user')
export class UserController {
constructor(
private readonly userService: UserService,
private authService: AuthService) { }
@Post('register')
@UsePipes(new ValidationPipe({ transform: true }))
register(@Body() createUserDto: CreateUserDto) {
return this.userService.register(createUserDto);
}
@Post('login')
@UsePipes(ValidationPipe)
@Redirect('/auth/login')
async login(@Request() req) { }
@UseGuards(JwtGuard)
@Get()
findAll(@Query() query: ExpressQuery) {
return this.userService.findAll(query);
}
@UseGuards(JwtGuard)
@Get(':id')
findOne(@Param('id') id: string) {
return this.userService.findOne(id);
}
@UseGuards(JwtGuard)
@Patch()
update(@Body() updateUserDto: UpdateUserDto) {
return this.userService.update(updateUserDto);
}
@UseGuards(JwtGuard)
@Delete(':id')
remove(@Param('id') userId: string, @Body('id') deleteId: string) {
return this.userService.remove(userId, deleteId);
}
}
This my userModule
import { Module } from '@nestjs/common';
import { UserService } from './user.service';
import { UserController } from './user.controller';
import { JwtModule } from '@nestjs/jwt';
import { User, UserSchema } from './schemas/user_schema';
import { MongooseModule } from '@nestjs/mongoose';
import { PasswordService } from 'src/password/password.service';
import { JwtStrategy } from 'src/auth/strategies/jwt-strategy';
import { AuthModule } from 'src/auth/auth.module';
import { PassportModule } from '@nestjs/passport';
import { AuthService } from 'src/auth/auth.service';
@Module({
imports: [
MongooseModule.forFeature([{ name: User.name, schema: UserSchema }]),
JwtModule.register({
secret: `${process.env.SECRET}`,
signOptions: { expiresIn: '1h' },
}),
AuthModule,
],
controllers: [UserController],
providers: [UserService, PasswordService, JwtStrategy, PassportModule, AuthService],
})
export class UserModule { }
and this is my
import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { AuthController } from './auth.controller';
import { UserService } from 'src/user/user.service';
import { JwtModule, JwtService } from '@nestjs/jwt';
import { LocalStrategy } from './strategies/local-strategies';
import { MongooseModule } from '@nestjs/mongoose';
import { User, UserSchema } from 'src/user/schemas/user_schema';
import { PasswordService } from 'src/password/password.service';
import { PassportModule } from '@nestjs/passport';
import { JwtStrategy } from './strategies/jwt-strategy';
import { RefreshJwtStrategy } from './strategies/refreshToken.strategy';
@Module({
providers: [
AuthService,
UserService,
LocalStrategy,
PasswordService,
JwtStrategy,
RefreshJwtStrategy
],
controllers: [AuthController],
imports: [
MongooseModule.forFeature([{ name: User.name, schema: UserSchema }]),
JwtModule.register({
secret: `${process.env.SECRET}`,
signOptions: { expiresIn: '1d' },
}),
PassportModule],
exports: [AuthService, LocalStrategy, JwtStrategy],
})
export class AuthModule { }
Knowing that the local guard works fine with the login to my knowledge
I have tried rechecking the token making sure that the .env file works properly
in the passport you just allow to use
function verify(username, password)
you can't use emailthe only way is change
username
field name is this: