angular / mobile-toolkit

Tools for building progressive web apps with Angular
MIT License
1.34k stars 175 forks source link

Service Worker works behind Authentication? #176

Open mattma opened 7 years ago

mattma commented 7 years ago

Trying to run Service worker behind Authentication. It works 100% without Authentication. Once I enabled the auth, I failed with (401 Authentication) getting the $SITE_URL/ngsw-manifest.json?...$timestamp$...

Because the service worker cannot read the file of ngsw-manifest.json, none of those assets is being downloaded to the browser cache.

By reading the source code of service worker, currently refresh method with req url, $SITE_URL/ngsw-manifest.json?...$timestamp$... is being loaded with Fetch API.

Current option for the fetch api when it requests ngsw-manifest.json that behind of Authentication is

        request.mode = 'cors';
        request.credentials = 'omit';

What if i changed to

        request.mode = 'no-cors';
        request.credentials = 'include';

Is it supposed to work? Do @alxhub have any suggestion on how to work around this issue? thanks

mattma commented 7 years ago

Tried with `request.mode = 'cors'; option inside fetch method, the browser raised an error

Note: worker-basic.min.js code has been replaced with unminified version of worker-basic.js

worker-basic.min.js:117 Uncaught (in promise) TypeError: Cannot assign to read only property 'mode' of object '#<Request>'
    at NgSwFetch.refresh (worker-basic.min.js:117)
    at Driver.fetchManifestFromNetwork (worker-basic.min.js:2755)
    at Driver.doInstallFromNetwork (worker-basic.min.js:2708)
    at worker-basic.min.js:2666
    at <anonymous>

I am sure that if we could succeed on fetching ngsw-manifest.json that sit behind the auth, we should be ok to get all assets cached locally.

Here is a thing, worker-basic.min.js is the initiator of fetching ngsw-manifest.json request. worker-basic.min.js also sit behind the auth, it works fine. I think it is being added the order after index.html is being loaded. at that time, the browser window has already authenticated with correct Username and Password. How come ngsw-manifest.json located right next to the worker-basic.min.js in the same folder that cannot be fetched with 401 status error?

alxhub commented 7 years ago

Hi there @mattma,

I've not tested this scenario before, but we definitely want to support caching authenticated content. Obviously that comes with certain security considerations that we'll have to address.

I don't believe no-cors is needed here as it's unlikely you're expecting the SW to retrieve the manifest cross-origin. Instead, we probably just need to send the request with credentials.

I will take on the task of investigating this.

mattma commented 7 years ago

@alxhub thanks for your reply.

// response header
Authenticate:Basic realm="credentials goes here"

I do believe that If i pass my username and password and generate an Auth token, it will probably work because it requires the Basic Auth.

Here is a thing, does it have any security concern on leaking it out here if someone is able to decode the token?

If that is the only way to handle this case, does Angular-cli inside project's .angular-cli.json has an option. "serviceWorker": true,, should it become as an object that I can pass the username/password in it? but if I do the username and password hard code inside the file, and most likely this file will be version controlled, cause it may need to be used by CI/CD, that may leak the credential out.

I do not believe that .angular-cli.json takes any environment variables at this point.

Thanks for looking into this use case. Looking forward for "@angular/service-worker": "1.0.0-beta.17"

mattma commented 7 years ago

@alxhub I know that you are working pretty hard on new HttpClient api. I have used it and loved the new implementation very much! Do you have time to visit this issue?