简体   繁体   English

使用 jwt 和护照在 NestJS 中的授权问题

[英]Trouble with authorization in NestJS using jwt and passport

I have a ruby on rails api that will connect to a nestjs api that i'm making from scratch.我在轨道 api 上有一个 ruby,它将连接到我从头开始制作的 Nestjs api。 I will create a jwt token on rails and use it as the authorization, using the same signature on both projects.我将在 Rails 上创建一个 jwt 令牌并将其用作授权,在两个项目上使用相同的签名。 For now, i'm testing only via postman calling the NestJS api, but it is returning "UNAUTHORIZED" on every request.目前,我仅通过调用 NestJS api 的 postman 进行测试,但它在每个请求上都返回“未经授权”。 Here's a little bit of my code:这是我的一些代码:

jwt.doctor.strategy.ts jwt.doctor.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 JwtDoctorStrategy extends PassportStrategy( Strategy, 'jwt.doctor', ) { constructor(config: ConfigService) { super({ jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(), secretOrKey: config.get('JWT_DOCTOR_SECRET'), }); } validate(payload: any) { console.log({ payload, }); return payload; } }

PS: i created two strategies because i have different signatures for different cases. PS:我创建了两种策略,因为我对不同的情况有不同的签名。 The other one is very similar to this one, but for now i'm only tested the one i provided above.另一个与这个非常相似,但现在我只测试了我上面提供的那个。

doctor.controller.ts医生.controller.ts

 import { Controller, Get, UseGuards } from '@nestjs/common'; import { AuthGuard } from '@nestjs/passport'; @Controller('doctors') export class DoctorController { @UseGuards(AuthGuard('jwt.doctor')) @Get('me') getMe() { return 'User info'; } }

Am i missing something?我错过了什么吗? I'm creating the jwt token in the console for test purposes, and its being validated ok on the jwt website.我正在控制台中创建 jwt 令牌以用于测试目的,并且在 jwt 网站上对其进行了验证。 Would appreciate very much any insights (:非常感谢任何见解(:

We can pass an options object in the call to super() to customize the behavior of the passport strategy.我们可以在对 super() 的调用中传递一个选项 object 来自定义护照策略的行为。 In this example, the passport-local strategy by default expects properties called username and password in the request body.在此示例中,默认情况下,passport-local 策略需要请求正文中名为 username 和 password 的属性。 Pass an options object to specify different property names, for example: super({ usernameField: 'email' })传递一个选项 object 来指定不同的属性名称,例如: super({ usernameField: 'email' })

import { ExtractJwt, Strategy } from 'passport-jwt';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable } from '@nestjs/common';
import { jwtConstants } from './constants';

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor() {
    super({
       usernameField: 'email' // your strategy here in super
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      ignoreExpiration: false,
      secretOrKey: jwtConstants.secret,
    });
  }

  async validate(payload: any) {
    return { userId: payload.sub, email: payload.email };
  }
}

Also Assuming that your other Modules are importing the AuthModule in order to have access to the AuthService you could just re-export the PassportModule:还假设您的其他模块正在导入 AuthModule 以访问 AuthService,您可以重新导出 PassportModule:

const passportModule = PassportModule.register({ defaultStrategy: 'jwt' });

@Module({
  imports: [
    passportModule,
    JwtModule.register({
      secretOrPrivateKey: 'secretKey',
      signOptions: {
        expiresIn: 3600,
      },
    }),
    UsersModule,
  ],
  providers: [AuthService, JwtStrategy],
  exports: [passportModule]
})
export class AuthModule {}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM