我正在尝试实施护照策略(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 [];
}
}
感谢您的帮助!
答案 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);
}