henrbu
henrbu

Reputation: 208

NestJS passport-jwt always throws Unauthorized

I encountered to the issue that whenever I sign up through the postman I receive the token. However, other route is private and requires token as Authorization Bearer, but whenever I put the token I receive "Unauthorized". The validate from strategy never executes, as I understand because the token for some reasons is invalid. Important to mention, that I do not receive any errors.

jwt.strategy.ts:

import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { PassportStrategy } from '@nestjs/passport';
import { ExtractJwt, Strategy } from 'passport-jwt';

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor(config: ConfigService) {
    super({
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      secretOrKey: config.get('JWT_SECRET'),
    });
  }

  async validate(payload: any) {
    console.log({ payload: payload });
    return true;
  }
}

auth.module.ts

import { Module } from '@nestjs/common';
import { JwtModule } from '@nestjs/jwt';
import { AuthController } from './auth.controller';
import { AuthService } from './auth.service';
import { JwtStrategy } from './strategy';

@Module({
  imports: [JwtModule.register({})],
  controllers: [AuthController],
  providers: [AuthService, JwtStrategy],
})
export class AuthModule {}

auth.service.ts where I receive token:

public async signin(body: AuthDto) {
    // find the user by email
    const user = await this.prisma['User'].findUnique({
      where: {
        email: body.email,
      },
    });

    // if user does not exists throw exception
    if (!user) {
      throw new ForbiddenException('Invalid email address or password');
    }

    // compare passwords
    const passwordMatches = await argon.verify(user.hash, body.password);

    // if password is inoccrect throw exception
    if (!passwordMatches) {
      throw new ForbiddenException('Invalid email address or password');
    }

    return this.signToken(user.id, user.email);
  }

auth.service.ts where I create the token:

private async signToken(userId: number, email: string): Promise<{ access_token: string }> {
    const payLoad = {
      sub: userId,
      email,
    };

    const token = await this.jwt.sign(payLoad, {
      expiresIn: '10m',
      secret: this.config.get('JWT_SECRET'),
    });

    return { access_token: token };
  }
}

user.controller.ts where the private route is

import { Controller, Get, UseGuards } from '@nestjs/common';
import { JwtGuard } from 'src/auth/guard';

@Controller('users')
export class UserController {
  @UseGuards(JwtGuard)
  @Get('me')
  getMe() {
    return 'Hello JWT';
  }
}

jwt.guard.ts

import { AuthGuard } from '@nestjs/passport';

export class JwtGuard extends AuthGuard('jwt') {
  constructor() {
    super();
  }
}

Upvotes: 0

Views: 313

Answers (1)

henrbu
henrbu

Reputation: 208

The code works fine, without any issues. However, the issues was with the postman. For some reasons the Authorization tab were bugged, tried to sent through headers written by hand and that worked without any problems

Upvotes: 0

Related Questions