不能通过NestJS护照策略请求用户(文档示例除外)

时间:2019-11-26 06:41:04

标签: passport.js nestjs

我正在尝试实施护照策略(passport-headerapikey),我能够使其发挥作用,并且可以确保自己的路线安全。 但是请求为空,无法访问已登录的用户吗?

import { HeaderAPIKeyStrategy } from "passport-headerapikey";
import { PassportStrategy } from "@nestjs/passport";
import { Injectable, NotFoundException } from "@nestjs/common";
import { CompanyService } from "../../companies/companies.service";

@Injectable()
export class ApiKeyStrategy extends PassportStrategy(HeaderAPIKeyStrategy, "api-key") {
  constructor(private readonly companyService: CompanyService) {
    super(
      {
        header: "Authorization",
        prefix: "Api-Key "
      },
      true,
      async (apiKey, done) => {
        return this.validate(apiKey, done);
      }
    );
  }

  public async validate(apiKey: string, done: (error: Error, data) => {}) {
    const company = await this.companyService.findByApiKey(apiKey);
    if (company === null) {
      throw new NotFoundException("Company not found");
    }
    return company;
  }
}


@UseGuards(AuthGuard("api-key"))
export class CompaniesController {
  constructor(private companyService: CompanyService) {}
  @Get()
  @ApiOperation({ title: "Get company information" })
  public getCompany(@Request() req) {
    // here request is empty, so i cannot access the user..
    console.log("request", req);
    return [];
  }
}


感谢您的帮助!

3 个答案:

答案 0 :(得分:1)

要访问登录的用户,可以将对象注入请求中。为此,请在您的ApiKeyStrategy构造函数中,将第三个参数更改为如下所示:

async (apiKey, verified, req) => {
  const user = await this.findUser(apiKey);
  // inject the user in the request
  req.user = user || null;
  return verified(null, user || false);
}

现在,您可以访问登录的用户:

getCompany(@Request() req) {
  console.log(req.user);
}

我希望能对您有所帮助。

答案 1 :(得分:0)

如文档中所示,您应该做一些工作来获取当前用户:documetation

首先在app.module中确保设置了上下文:

context: ({ req }) =>  ({ req })

然后您可以在控制器/解析器中添加它,此示例使用Gql(GraphQL):

export const CurrentUser = createParamDecorator(
  (data: unknown, context: ExecutionContext) => {
     const ctx = GqlExecutionContext.create(context);
     return ctx.getContext().req.user;
  },
);

如果这对您不起作用,请尝试以下方法:

export const CurrentUser = createParamDecorator(
  (data: unknown, context: ExecutionContext) => {
    const ctx = GqlExecutionContext.create(context);
    const request  = ctx.getContext();
    request.body = ctx.getArgs();
    return request.user;
  },
);

答案 2 :(得分:-1)

按如下方式修改您的validate方法:

public async validate(apiKey: string, done: (error: Error, data) => {}) {
    const company = await this.companyService.findByApiKey(apiKey);
    if (company === null) {
      return done(new NotFoundException("Company not found"), null);
    }
    return done(null, company);
  }