0

When a browser requests an image from the server, the call is getting picked up by an API controller in the back end. There, a authorization check must be done before returning the image in order to check if the request is allowed or not.

So I need to add the authorization header and when searching for the best solution, I found this article: https://www.twelve21.io/how-to-access-images-securely-with-oauth-2-0/ and I was mostly intereseted in the solution number 4 which uses a Service Worker.

I made my own implementation, I registered a serviceWorker:

if ('serviceWorker' in navigator) {
    console.log("serviceWorker active");
    window.addEventListener('load', onLoad);
}
else {
    console.log("serviceWorker not active");
}

function onLoad() {
    console.log("onLoad is called");
    var scope = {
        scope: '/api/imagesgateway/'
    };
    navigator.serviceWorker.register('/Scripts/ServiceWorker/imageInterceptor.js', scope)
        .then(registration => console.log("ServiceWorker registration successful with scope: ", registration.scope))
        .catch(error => console.error("ServiceWorker registration failed: ", error));
}

and this is in my imageInterceptor:

self.addEventListener('fetch', event => {
    console.log("fetch event triggered");
    event.respondWith(
        fetch(event.request, {
            mode: 'cors',
            credentials: 'include',
            header: {
                'Authorization': 'Bearer ...'
            }
        })
    )
});

When I run my application, I see in my console that the registration seems to be successfully executed as I see the console.logs printed (ServiceWorker active, onLoad is called and successful registration with correct scope: https://localhost:44332/api/imagesgateway/

But when I load an image (https://localhost:44332/api/imagesgateway/...) via the gateway, I still get a 400 and when put a breakpoint on the backend I see that the authentication header is still null. Also, I don't see "fetch event triggered" message in my console. In another article it is stated that I can see the registered service workers via this setting: chrome://inspect/#service-workers but I don't see my worker there either.

My question is: Why isn't the authorization header added? Is it because, although the registration seems to go successfully, this isn't actually the case and therefore I don't see the worker in inspect#service-workers either?

Cornelis
  • 1,729
  • 5
  • 23
  • 39

2 Answers2

1

You're not seeing fetch event triggered in the browser console because your Service Worker script isn't allowed to intercept the image requests. This is because your Service Worker script is located in a directory outside the scope of the requests you're interested in.

In order to intercept requests that handle resources at /api/imagesgateway/ the SW script needs to be located in either /, /api/, or /api/imagesgateway/. It cannot be located in /some/other/directory/service-worker.js.

This is the reason that your Service Worker registers successfully! There is no probelm in registering the SW. The problem lies in what it can do.

More info: Understanding Service Worker scope

pate
  • 4,937
  • 1
  • 19
  • 25
  • I see now I forgot to mention that I try to implement the Service Worker in an ASP.NET MVC web application. I had to add a setting to the web.config () In the meanwhile I got the service worker working but now I am getting 2 request in my API for one image request. But I believe that is a different problem. – Cornelis Mar 27 '20 at 13:26
0

I have the similar issue. I've registered a Service Worker for right scope. But something goes wrong. The main goal of my SW is intercepting browser's requests to static files of remote RestAPI. These requests are generated by <img> and <iframe> elements of my html-page.

And something strange is observed: requests from <iframe> tags are handled properly, all works fine. But requests from <img> tags are not passed through Service Worker! For example if I put URL of requested image into <iframe> element the request is handled by SW. But! If I use <img> element with the same image`s URL - the request doesn't intercepted by Service Worker. Why?

Max Dubrovin
  • 11
  • 1
  • 2
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jun 21 '23 at 19:10