5

我使用 service worker 拦截对安全资源的 HTTP 请求并向请求添加授权标头(如果用户已经登录)。现在,我有一个场景,服务工作者拦截一个 POST 请求以注入授权标头。但是,服务工作者没有接收到请求有效负载中的数据,因此没有请求有效负载(参见屏幕截图 2)。因此,nodejs 中的后端验证逻辑失败,因为没有接收到有效负载数据。理想情况下,除了授权标头之外,后端代码还应该接收有效负载数据以保存在数据库中。有什么指导吗?

下面的第一个屏幕截图是带有有效负载的原始请求。第二个到服务工作者的请求没有任何请求有效负载。

这是我拦截获取请求的服务工作者代码:

self.addEventListener('fetch', (event) => {
  const fetchEvent = event;
  const requestProcessor = (idToken) => {
    console.log('idToken in fetch '+idToken);
    let req = event.request;
    // For same origin https requests, append idToken to header.
    if (self.location.origin == getOriginFromUrl(event.request.url) &&
        (self.location.protocol == 'https:' ||
         self.location.hostname == 'localhost') &&
        idToken) {
      // Clone headers as request headers are immutable.
      const headers = new Headers();
      for (let entry of req.headers.entries()) {
        headers.append(entry[0], entry[1]);
      }
      // Add ID token to header. We can't add to Authentication header as it
      // will break HTTP basic authentication.
      headers.append('Authorization', 'Bearer ' + idToken);
      try {
        req = new Request(req.url, {
          method: req.method,
          headers: headers,
          mode: 'same-origin',
          credentials: req.credentials,
          cache: req.cache,
          redirect: req.redirect,
          referrer: req.referrer,
          body: req.body,
          bodyUsed: req.bodyUsed,
          context: req.context
        });
      } catch (e) {
        console.error('failed to prepare new header '+ e);
        // This will fail for CORS requests. We just continue with the
        // fetch caching logic below and do not pass the ID token.
      }
    }

    return fetch(req);

  };
  // Try to fetch the resource first after checking for the ID token.
// getIdToken() returns valid idtoken for logged in user.
  event.respondWith(getIdToken().then(requestProcessor, requestProcessor));
});

  • Service Worker 执行前的原始请求

Service Worker 处理的请求

问候, 桑托什

4

2 回答 2

1

这实际上非常简单,假设有效负载是请求的主体。获取/访问它的具体方式取决于请求正文的内容类型:

event.request.arrayBuffer() // for content-type of arrayBuffer
event.request.blob()        // for content-type of blob
event.request.json()        // for content-type of json
event.request.text()        // for content-type of text
event.request.formData()    // for content-type of formData

每个人都返回一个承诺。

这归功于https://stackoverflow.com/a/39653321/1971662

于 2020-08-20T00:20:46.277 回答
0

我很努力地解决了这个问题,我用下面的代码找到了解决方案

async function handle(request) {
let newUrl = new URL(request.url)
return await fetch(newUrl, {
    ...request,
    headers: { 'Authorization': 'Bearer ' + access_token }
  }); 
}

self.addEventListener('fetch', function (event) {
    event.respondWith(handle(event.request)) 
}

浏览器网络选项卡是多个请求,一个请求发送到服务器。

于 2019-12-24T08:17:27.833 回答