Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to receive request payload in service worker?

I've used service worker to intercept HTTP requests to a secure resource and add authorization header to the request (if the the user is already logged in). Now, I have a scenario where a service worker intercepts a POST request to inject authorization header. But, the service worker is not receiving the data in request payload and hence, doesn't have a request payload (see screenshot 2). As a result the backend validation logic in nodejs fails, since, no payload data is received. Ideally, apart from authorization header the backend code should also receive payload data to persist in the DB. Any guidance ?

The first screenshot below is the original request with payload.The 2nd one to service worker doesn't have any request payload.

Here's my service worker code to intercept fetch requests:

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));
});

  • Original request before service worker execution

Service worker processed request

Regards, Santosh

like image 676
Santosh Kashyap Avatar asked Nov 06 '22 11:11

Santosh Kashyap


1 Answers

This is actually pretty simple, assuming the payload is the body of the request. The specific way to get/access it depends on the content type of the request's body:

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

Each of those return a promise.

Credit for this goes to https://stackoverflow.com/a/39653321/1971662.

like image 193
Isaac Gregson Avatar answered Dec 10 '22 22:12

Isaac Gregson