Nestjs authentication does not work in docker container

600 views Asked by At

I developed an full stack app using Angular as the frontend and Nestjs as the backend. The project is organized in a monorepository with NX. The project works fine on my local machine, including authentication (Passport library from Nestjs).

So I decided to dockerize the app, but when the app is run in the docker container the protected routes from the Nestjs backend are not accessible and I am getting a 401 error despite using the JWT token that I got from the same instance running in the docker container.

I migrated the project from bcrypt to bcryptjs because I was getting an error when building the docker container. The thing that confuses me mostly is that on my local machine everything works fine, but in the docker container the protected routes are not accessible despite using the JWT token that I got from the backend.

Dockerfile

FROM node:14
ENV PORT=3333
WORKDIR /app
COPY ["package.json", "package-lock.json*", "npm-shrinkwrap.json*","nx.json", "./"]
RUN npm install 
COPY ./apps .
EXPOSE 3333
CMD npm start

docker-compose.yml

version: '3.4'

services:
  myapp:
    image: myapp
    build:
      context: .
      dockerfile: ./Dockerfile
    volumes:
      - .:/app
    depends_on:
      - postgres
    environment:
      API_PORT: 3333
      JWT_SECRET: verystrongsecret
      JWT_EXPIRES_IN: 3600
      DB_TYPE: postgres
      DB_PORT: 5432
      DB_HOST: postgres
      DB_USERNAME: user
      DB_PASSWORD: password
      DB_NAME: db
      NODE_ENV: development
      TYPEORM_SYNC: 'true'
    ports:
      - 3333:3333

  postgres:
    image: postgres:10.4
    ports:
      - 5432:5432
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: password
      POSTGRES_DB: db

How to solve the issue with the authentication? What could cause docker to this strange behavior?

JwtStrategy:

export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor(
    @InjectRepository(UserRepository) private userRepository: UserRepository
  ) {
    super({
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      secretOrKey: process.env.JWT_SECRET || config.get('jwt.secret'),
    });
  }

  async validate(payload: JwtPayload): Promise<User> {
    const { email } = payload;
    const user = await this.userRepository.findOne({ email });

    if (!user) {
      throw new UnauthorizedException();
    }

    return user;
  }
}

to protect the routes I am using the : @UseGuards(AuthGuard()) where AuthGuard is from the passport library.

The AuthModule:

@Module({
  imports: [
    PassportModule.register({ defaultStrategy: 'jwt' }),
    JwtModule.register({
      secret: process.env.JWT_SECRET || jwtConfig.secret,
      signOptions: {
        expiresIn: process.env.JWT_EXPIRES_IN || jwtConfig.expiresIn,
      },
    }),
    TypeOrmModule.forFeature([UserRepository]),
  ],
  controllers: [AuthController],
  providers: [AuthService, JwtStrategy],
  exports: [AuthService, JwtStrategy, PassportModule],
})
export class AuthModule {}
0

There are 0 answers