title: JwtModule.registerAsync not working in NestJS
body: <p>I'm working on a NestJS project and I need to use JWT with <code>.env</code> configuration. It generates the token but when trying to access the secured url(With Authorization header), it just returns the Unauthorized message.</p>
  
  <p>jwt.strategy.ts</p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-html lang-html prettyprint-override"><code>import { Injectable, UnauthorizedException, Logger } from '@nestjs/common';
  import { PassportStrategy } from '@nestjs/passport';
  import { ExtractJwt, Strategy } from 'passport-jwt';
  import { AuthService } from './auth.service';
  import { JwtPayload } from './interfaces/jwt-payload.interface';
  
  @Injectable()
  export class JwtStrategy extends PassportStrategy(Strategy) {
  
      constructor(private readonly authService: AuthService) {
          super({
              jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
              secretOrKey: process.env.JWT_SECRET_KEY,
          });
      }
  
      async validate(payload: JwtPayload) {
          const user = await this.authService.validateUser(payload);
          if (!user) {
              throw new UnauthorizedException();
          }
  
          return user;
      }
  }</code></pre>
  </div>
  </div>
  </p>
  
  <p>auth.module.ts</p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-html lang-html prettyprint-override"><code>import { Module } from '@nestjs/common';
  import { AuthService } from './auth.service';
  import { AuthController } from './auth.controller';
  import { PassportModule } from '@nestjs/passport';
  import { JwtModule } from '@nestjs/jwt';
  import { JwtStrategy } from './jwt.strategy';
  
  @Module({
    imports: [
      PassportModule.register({ defaultStrategy: 'jwt' }),
      JwtModule.registerAsync({
        useFactory: async () =&gt; ({
          secretOrPrivateKey: process.env.JWT_SECRET_KEY,
          signOptions: {
            expiresIn: process.env.JWT_EXPIRATION_TIME,
          },
        }),
      }),
    ],
    providers: [AuthService, JwtStrategy],
    controllers: [AuthController],
  })
  export class AuthModule {}</code></pre>
  </div>
  </div>
  </p>
  
  <p>main.ts</p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-html lang-html prettyprint-override"><code>import { NestFactory } from '@nestjs/core';
  import * as dotenv from 'dotenv';
  import { ApiModule } from './api/api.module';
  import { Logger } from '@nestjs/common';
  
  async function bootstrap() {
    dotenv.config({ path: './.env'});
    const app = await NestFactory.create(ApiModule);
    const port = process.env.APP_PORT;
  
    await app.listen(port);
    Logger.log(`Server started on http://localhost:${port}`);
  }
  bootstrap();</code></pre>
  </div>
  </div>
  </p>
  
  <p>Looks like <strong><code>JwtModule.registerAsync</code></strong> is not working with environment variables. I've tried many things but it always fails.
  If I change environment variables in <code>auth.module.ts</code> for static data, then it works fine.
  Something like this:</p>
  
  <pre><code>secretOrPrivateKey: 'secretKey',
  signOptions: {
    expiresIn: 3600,
  },
  </code></pre>
  
  <p><strong>UPDATE</strong>
  Project structure</p>
  
  <pre><code>- src
      - api
          - auth
              - interfaces
                  jwt-payload.interface.ts
              auth.controller.ts
              auth.module.ts
              auth.service.ts
              jwt.strategy.ts
              index.ts
          api.module.ts
          index.ts
      main.ts
  - test
  .env
  </code></pre>
  
  <p>My main.ts looks like this now.</p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-html lang-html prettyprint-override"><code>import { NestFactory } from '@nestjs/core';
  import * as dotenv from 'dotenv';
  import { resolve } from 'path';
  import { ApiModule } from './api/api.module';
  import { Logger } from '@nestjs/common';
  
  async function bootstrap() {
    dotenv.config({ path: resolve(__dirname, '../.env') });
    const app = await NestFactory.create(ApiModule);
    const port = process.env.APP_PORT;
  
    await app.listen(port);
    Logger.log(`Server started on http://localhost:${port}`);
  }
  bootstrap();</code></pre>
  </div>
  </div>
  </p>
  
  <p>You see that my <code>.env</code> is in the root of the project.</p>