NestJS 拦截器 - 将数据附加到传入请求 Header 或 Body
NestJS Interceptor - Append data to incoming request Header or Body
我正在尝试修改 NestJS 传入请求并将一些数据附加到 header 或 Body。我能够用我的数据替换所有 body 数据,但我想附加而不是删除传入的 body 数据。
这是我的代码
export class MyInterceptor implements NestInterceptor {
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
const request = context.switchToHttp().getRequest();
const token = request.headers['authorization'];
if (token) {
const decoded = jwt_decode(token);
request.body['userId'] = decoded['id'];
}
return next.handle();
}
}
提前致谢
我添加了两个示例,因为在 运行 测试拦截器之后,它顺利通过了。当然,我的示例将与您的设置大不相同,但是,希望它能给您足够的洞察力:
测试文件:
test('should not mutate entire request body object', () => {
const dto = {
username: 'testuser',
email: 'test@domain.com',
};
const headers = {
authorization: 'Bearer sdkfjdsakfjdkjfdal',
};
return request(app.getHttpServer())
.post('/')
.send(dto)
.set(headers)
.expect(({ body }) => {
expect(body.userId).toBeDefined();
delete body.userId;
expect(body).toStrictEqual(dto);
});
});
我理解您的问题是试图获取有关经过身份验证的用户的信息,return it/use 稍后?但是,您当前的实现似乎完全覆盖了 request.body
而不是将 属性 附加到原始对象。
拦截器:
@Injectable()
export class HttpRequestBodyInterceptor implements NestInterceptor {
intercept(context: ExecutionContext, next: CallHandler): Observable {
const request = context.switchToHttp().getRequest();
const token = request.headers['authorization'];
if (token) {
// decode token
request.body['userId'] = 'user_123456789';
}
return next.handle();
}
}
</pre>
控制器:
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
@Post()
@UseInterceptors(HttpRequestBodyInterceptor)
getHello(@Req() req): string {
return req.body;
}
}
</pre>
这个 return 是正确的答案,测试将通过。但是,您可能会发现更可靠的解决方案是:
@Injectable()
export class HttpRequestBodyInterceptor implements NestInterceptor {
intercept(context: ExecutionContext, next: CallHandler): Observable {
const request = context.switchToHttp().getRequest();
const token = request.headers['authorization'];
if (token) {
// decode token
request.userId = 'user_123456789';
}
return next.handle();
}
}
</pre>
然后通过以下方式在您的控制器中访问它:
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
@Post()
@UseInterceptors(HttpRequestBodyInterceptor)
getHello(@Req() req) {
return {
userId: req.userId,
...req.body,
};
}
}
</pre>
最后,如果您对拦截器的唯一需求是获取 userId
属性,您可能会发现 https://docs.nestjs.com/security/authentication#jwt-functionality 很有用。
我正在尝试修改 NestJS 传入请求并将一些数据附加到 header 或 Body。我能够用我的数据替换所有 body 数据,但我想附加而不是删除传入的 body 数据。
这是我的代码
export class MyInterceptor implements NestInterceptor {
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
const request = context.switchToHttp().getRequest();
const token = request.headers['authorization'];
if (token) {
const decoded = jwt_decode(token);
request.body['userId'] = decoded['id'];
}
return next.handle();
}
}
提前致谢
我添加了两个示例,因为在 运行 测试拦截器之后,它顺利通过了。当然,我的示例将与您的设置大不相同,但是,希望它能给您足够的洞察力:
测试文件:
test('should not mutate entire request body object', () => {
const dto = {
username: 'testuser',
email: 'test@domain.com',
};
const headers = {
authorization: 'Bearer sdkfjdsakfjdkjfdal',
};
return request(app.getHttpServer())
.post('/')
.send(dto)
.set(headers)
.expect(({ body }) => {
expect(body.userId).toBeDefined();
delete body.userId;
expect(body).toStrictEqual(dto);
});
});
我理解您的问题是试图获取有关经过身份验证的用户的信息,return it/use 稍后?但是,您当前的实现似乎完全覆盖了 request.body
而不是将 属性 附加到原始对象。
拦截器:
@Injectable() export class HttpRequestBodyInterceptor implements NestInterceptor { intercept(context: ExecutionContext, next: CallHandler): Observable { const request = context.switchToHttp().getRequest(); const token = request.headers['authorization']; if (token) { // decode token request.body['userId'] = 'user_123456789'; } return next.handle(); } } </pre>
控制器:
@Controller() export class AppController { constructor(private readonly appService: AppService) {} @Post() @UseInterceptors(HttpRequestBodyInterceptor) getHello(@Req() req): string { return req.body; } } </pre>
这个 return 是正确的答案,测试将通过。但是,您可能会发现更可靠的解决方案是:
@Injectable() export class HttpRequestBodyInterceptor implements NestInterceptor { intercept(context: ExecutionContext, next: CallHandler): Observable { const request = context.switchToHttp().getRequest(); const token = request.headers['authorization']; if (token) { // decode token request.userId = 'user_123456789'; } return next.handle(); } } </pre>
然后通过以下方式在您的控制器中访问它:
@Controller() export class AppController { constructor(private readonly appService: AppService) {} @Post() @UseInterceptors(HttpRequestBodyInterceptor) getHello(@Req() req) { return { userId: req.userId, ...req.body, }; } } </pre>
最后,如果您对拦截器的唯一需求是获取
userId
属性,您可能会发现 https://docs.nestjs.com/security/authentication#jwt-functionality 很有用。