Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

redirecting to Google OAuth flow in progressive web app

I've been working on an app using React and Next.js, currently adding PWA support.

Users log in to the app via the Google OAuth flow. I was originally using the JS client which utilizes a pop-up window, but that ran into errors in the PWA. I'm now using the normal OAuth flow by redirecting the user to Google's OAuth URL.

This works fine in the browser. In the standalone PWA on iOS, it opens the OAuth page in a new Safari window. This means that the OAuth flow is carried out in Safari, and at the end the user is left using the app in Safari rather than the standalone PWA.

I'm redirecting using this method:

export function setHref(newLocation: string) {
  window.location.href = newLocation;
}

This even looks to be the method everyone recommends to avoid pop-ups when redirecting in your PWA. Has this changed recently? Or is there another method to carry out redirects/OAuth flows inside a standalone progressive web app?

like image 636
Jakemmarsh Avatar asked Aug 23 '18 19:08

Jakemmarsh


3 Answers

I have a workaround that solve the oauth redirection problem on ios safari standalone web app.

The problem is the manifest meta tag, it seems that webkit (safari) implemented it with an old specification (Chromium had the same problem and fix it in a recent version).

I based the workaround by modifying Google´s PWACompat Javascript you can get on:

https://github.com/GoogleChromeLabs/pwacompat/blob/master/pwacompat.js

PWAcompat js is useful to generate the proper html meta tags, in order to have an standalone web app with home icons and an splash screen

You need to do a small "hack" on PwaCompat script and in your "manifest" meta tag by replacing the name of the meta tag by any identifier, for example, in your index.html:

<link rel="pwa-setup" href="manifest.json" >
<script async src="js/pwacompat.js"></script>

manifest.json contains your standard manifest.json declaration, with the name, icons and styling for your web app.

js/pwacompat.js, contains a copy of pwacompat.js from google, with this small modification ( line 36) :

Change :

const manifestEl = document.head.querySelector('link[rel="manifest"]');

by

const manifestEl = document.head.querySelector('link[rel="pwa-setup"]');

where pwa-setup is the name you place on meta tag, and that´s it, you have your manifest.json interpreted and oauth redirection in the same standalone context 🎉

UPDATE: From IOS 13 and above this workaround is not longer necessary. Anyway, if you want to keep the compatibility with IOS < 13, you can use the following script to check the IOS Version and condition the workaround use:

<script>

        var iOS = (/iP(hone|od|ad)/.test(navigator.userAgent));
        if (iOS) {
            var v = (navigator.appVersion).match(/OS (\d+)_(\d+)_?(\d+)?/);
            var iOSversion = parseInt(v[1], 10);
            console.log(iOSversion);
            if(iOSversion < 13) {
                document.querySelector('link[rel="manifest"]').setAttribute("rel", "no-on-ios");


            }
        }
</script>
like image 119
Jorge Valvert Avatar answered Sep 28 '22 10:09

Jorge Valvert


The good solution for now is to hack it through pwacompat. But on Android changing the manifest rel attribute to "pwa-setup" does not comply with webapp requirements thus the install to home popup doesn't appear.

<link rel="pwa-setup" href="manifest.json" >
<script async src="js/pwacompat.js"></script>

Changed line #36

const manifestEl = document.head.querySelector('link[rel="pwa-setup"]');

A better solution is to identify if the webapp is rendered on ios or android, then change the rel attribute in "runtime"

<link rel="manifest" href="manifest.json">
<link rel="pwa-setup" href="manifest.json">
<script src="pwacompat.js"></script>
<script>
   var iOS = !!navigator.platform && /iPhone|iPod/.test(navigator.platform);
   if(iOS) {
      document.querySelector('link[rel="manifest"]').setAttribute("rel", "no-on-ios");
   }
</script>
like image 37
Lester Avatar answered Sep 28 '22 08:09

Lester


I combined @Lester answer with @Roysh and a few more to make it more PWA replaceable on iOS. Since it lost manifest it will use title as default name and now open the current path instead of start_url from manifest.

<link rel="manifest" href="manifest.webmanifest">
<script>
  if (!!navigator.platform && /iP(?:hone|ad|od)/.test(navigator.platform)) {
    document.querySelector(`link[rel="manifest"]`).setAttribute(`rel`, `no-ios`);
    document.title = `AppName`; // default app name | simulate short_name
    if (`standalone` in window.navigator && window.navigator.standalone && sessionStorage.getItem(`iOS-redirect`) === null) {
      sessionStorage.setItem(`iOS-redirect`, ``);
      window.location = `/`; // simulate start_url
    }
  }
</script>
like image 20
hisoft Avatar answered Sep 28 '22 08:09

hisoft