Javascript NestJS拦截器-将数据附加到传入的请求头或请求体
我试图修改一个NestJS传入请求,并将一些数据附加到头或正文中。我可以用我的数据替换所有的身体数据,但我希望附加而不是删除传入的身体数据 这是我的密码Javascript NestJS拦截器-将数据附加到传入的请求头或请求体,javascript,node.js,nestjs,Javascript,Node.js,Nestjs,我试图修改一个NestJS传入请求,并将一些数据附加到头或正文中。我可以用我的数据替换所有的身体数据,但我希望附加而不是删除传入的身体数据 这是我的密码 export class MyInterceptor implements NestInterceptor { intercept(context: ExecutionContext, next: CallHandler): Observable<any> { const request = context.switch
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();
}
}
导出类MyInterceptor实现NestInterceptor{
拦截(上下文:ExecutionContext,下一步:CallHandler):可观察{
const request=context.switchToHttp().getRequest();
const token=request.headers['authorization'];
如果(令牌){
const decoded=jwt_decode(令牌);
request.body['userId']=解码的['id'];
}
返回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);
});
});
@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();
}
}
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
@Post()
@UseInterceptors(HttpRequestBodyInterceptor)
getHello(@Req() req): string {
return req.body;
}
}
我理解您的问题是试图获取有关已验证用户的信息,然后返回/稍后使用?但是,您当前的实现似乎完全覆盖了request.body
,而不是将您的属性附加到原始对象
拦截器:
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);
});
});
@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();
}
}
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
@Post()
@UseInterceptors(HttpRequestBodyInterceptor)
getHello(@Req() req): string {
return req.body;
}
}
@可注射()
导出类HttpRequestBodyInterceptor实现NestInterceptor{
拦截(上下文:ExecutionContext,下一步:CallHandler):可观察{
const request=context.switchToHttp().getRequest();
const token=request.headers['authorization'];
如果(令牌){
//解码令牌
request.body['userId']='user_123456789';
}
返回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);
});
});
@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();
}
}
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
@Post()
@UseInterceptors(HttpRequestBodyInterceptor)
getHello(@Req() req): string {
return req.body;
}
}
@控制器()
导出类AppController{
构造函数(私有只读appService:appService){}
@Post()
@UseInterceptors(HttpRequestBodyInterceptor)
getHello(@Req()Req):字符串{
返回请求主体;
}
}
这将返回正确的响应,测试将通过。但是,您可能会发现一个更可靠的解决方案是:
@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();
}
}
@可注射()
导出类HttpRequestBodyInterceptor实现NestInterceptor{
拦截(上下文:ExecutionContext,下一步:CallHandler):可观察{
const request=context.switchToHttp().getRequest();
const token=request.headers['authorization'];
如果(令牌){
//解码令牌
request.userId='user_123456789';
}
返回next.handle();
}
}
然后通过以下方式在控制器中访问此项:
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
@Post()
@UseInterceptors(HttpRequestBodyInterceptor)
getHello(@Req() req) {
return {
userId: req.userId,
...req.body,
};
}
}
@控制器()
导出类AppController{
构造函数(私有只读appService:appService){}
@Post()
@UseInterceptors(HttpRequestBodyInterceptor)
getHello(@Req()Req){
返回{
userId:req.userId,
…请求主体,
};
}
}
最后,如果您对拦截器的唯一需求是获取userId
属性,您可能会发现这很有用。上面的代码用我添加的内容替换所有传入的主体。我需要附加到body而不是replace而不是修改原始请求的body,您是否尝试过复制它,附加新属性,然后将副本重新分配给原始body属性?传入的body对于每个请求都不同,但通常类似于{'data':“value”}或者,您可以避免重新分配body,使用请求对象(request.userId),然后根据需要从控制器访问该属性。将@Req()Req
添加到控制器方法参数,然后使用Req.userId