Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/417.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript NestJS拦截器-将数据附加到传入的请求头或请求体_Javascript_Node.js_Nestjs - Fatal编程技术网

Javascript 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

我试图修改一个NestJS传入请求,并将一些数据附加到头或正文中。我可以用我的数据替换所有的身体数据,但我希望附加而不是删除传入的身体数据

这是我的密码

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