Аутентификация NestJS с помощью Auth0 через `passport-jwt` - PullRequest
0 голосов
/ 06 февраля 2019

Я пытаюсь создать проект NestJS, который использует Auth0 для аутентификации, с библиотекой passport-jwt (в сочетании с @nestjs/passport), хотя я не могу заставить его работать.Я не уверен, где я иду не так.Я перечитывал документы снова и снова, но все еще не могу найти проблему.

Код

/ src / auth / jwt.strategy.ts

import { Injectable, UnauthorizedException } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { ExtractJwt, Strategy } from 'passport-jwt';
import { passportJwtSecret } from 'jwks-rsa';
import { xor } from 'lodash';
import { JwtPayload } from './interfaces/jwt-payload.interface';

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor() {
    super({
      secretOrKeyProvider: passportJwtSecret({
        cache: true,
        rateLimit: true,
        jwksRequestsPerMinute: 5,
        jwksUri: `https://${process.env.AUTH0_DOMAIN}/.well-known/jwks.json`,
      }),

      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      audience: 'http://localhost:3000',
      issuer: `https://${process.env.AUTH0_DOMAIN}/`,
    });
  }

  validate(payload: JwtPayload) {
    if (
      xor(payload.scope.split(' '), ['openid', 'profile', 'email']).length > 0
    ) {
      throw new UnauthorizedException(
        'JWT does not possess the requires scope (`openid profile email`).',
      );
    }
  }
}

/ src / auth / interfaces / jwt-payload.interface

/* Doesn't do much, not really relevant */
import { JsonObject } from '../../common/interfaces/json-object.interface';

export interface JwtPayload extends JsonObject {
  /** Issuer (who created and signed this token) */
  iss?: string;
  /** Subject (whom the token refers to) */
  sub?: string;
  /** Audience (who or what the token is intended for) */
  aud?: string[];
  /** Issued at (seconds since Unix epoch) */
  iat?: number;
  /** Expiration time (seconds since Unix epoch) */
  exp?: number;
  /** Authorization party (the party to which this token was issued) */
  azp?: string;
  /** Token scope (what the token has access to) */
  scope?: string;
}

/ src / auth / auth.module.ts

import { Module } from '@nestjs/common';
import { JwtStrategy } from './jwt.strategy';
import { PassportModule } from '@nestjs/passport';

@Module({
  imports: [PassportModule.register({ defaultStrategy: 'jwt' })],
  providers: [JwtStrategy],
  exports: [JwtStrategy],
})
export class AuthModule {}

/ src / app.module.ts

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { AuthModule } from './auth/auth.module';

@Module({
  imports: [AuthModule],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

/ src / app.controller.ts

import { Controller, Get, UseGuards } from '@nestjs/common';
import { AppService } from './app.service';
import { AuthGuard } from '@nestjs/passport';

@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}

  @Get()
  getHello(): string {
    return this.appService.getHello();
  }

  @Get('protected')
  @UseGuards(AuthGuard())
  getProtected(): string {
    return 'This route is protected';
  }
}

Запрос на получение localhost:3000/protected С действительного токена на предъявителя приводит к ошибке {"statusCode":401,"error":"Unauthorized"}.

Полный источник можно найти по адресу https://github.com/jajaperson/nest-auth0

Заранее спасибо;Джеймс Дженсен

ОБНОВЛЕНИЕ

Хорошо, после установки функций обертки bodge-y ВЕЗДЕ , я думаю, что я нашел источникпроблема: каждый раз, когда запускается функция secretOrKeyProvider, done вызывается с невероятно знакомой (для меня) ошибкой SSL Error: UNABLE_TO_VERIFY_LEAF_SIGNATURE.Это связано с тем, что в моей школе раздражает брандмауэр / CA, что является самой раздражающей вещью в моей жизни.Единственный способ, который я нашел, чтобы обойти это до сих пор, это сделать опасный NODE_TLS_REJECT_UNAUTHORIZED=0 (я пытался использовать NODE_EXTRA_CA_CERTS, но пока что потерпел неудачу).По какой-то причине (хотя, вероятно, хорошей) мой обходной путь не работает в этой ситуации.

ОБНОВЛЕНИЕ

Мне удалось заставить NODE_EXTRA_CA_CERTS работать, заставляя меня прыгать вверх и внизкрича в восторге.

1 Ответ

0 голосов
/ 16 февраля 2019

Все, что мне нужно было сделать (как только я перестал получать ошибку UNABLE_TO_VERIFY_LEAF_SIGNATURE, все, что мне нужно было сделать, это вернуть payload, если она действительна.

/ src / auth / jwt.strategy.ts

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor() {
    super({
      secretOrKeyProvider: passportJwtSecret({
        cache: true,
        rateLimit: true,
        jwksRequestsPerMinute: 5,
        jwksUri: `https://${process.env.AUTH0_DOMAIN}/.well-known/jwks.json`,
      }),

      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      audience: 'http://localhost:3000',
      issuer: `https://${process.env.AUTH0_DOMAIN}/`,
    });
  }

  validate(payload: JwtPayload): JwtPayload {
    if (
      xor(payload.scope.split(' '), ['openid', 'profile', 'email']).length > 0
    ) {
      throw new UnauthorizedException(
        'JWT does not possess the requires scope (`openid profile email`).',
      );
    }
    return payload;
  }
}

Опять же, полный (теперь функциональный) исходный код можно найти по адресу https://github.com/jajaperson/nest-auth0.

...