перенаправление на поток Google OAuth в прогрессивном веб-приложении

Я работаю над приложением с использованием React и Next.js, в настоящее время добавляя поддержку PWA.

Пользователи регистрируются в приложении через поток Google OAuth. Первоначально я использовал JS-клиент, который использует всплывающее окно, но это столкнулось с ошибками в PWA. Теперь я использую обычный поток OAuth, перенаправляя пользователя на URL-адрес Google OAuth.

Это прекрасно работает в браузере. В автономном PWA на iOS он открывает страницу OAuth в новом окне Safari. Это означает, что поток OAuth выполняется в Safari, а в конце пользователь остается использовать приложение в Safari, а не в автономном PWA.

Я перенаправляю этот метод:

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

Это даже выглядит как метод, который каждый рекомендует избегать всплывающих окон при перенаправлении в вашем PWA. Это изменилось недавно? Или существует другой метод для выполнения перенаправления/потоков OAuth внутри автономного прогрессивного веб-приложения?

Ответ 1

У меня есть обходной путь, который решает проблему перенаправления oauth в автономном веб-приложении ios safari.

Проблема заключается в метатеге манифеста, похоже, что webkit (safari) реализовал его со старой спецификацией (у Chromium была та же проблема, и она была исправлена в последней версии).

Я основал обходной путь, изменив Javascript Google PWACompat, который вы можете использовать:

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

PWAcompat js полезен для генерации правильных HTML-метатегов, в порядке иметь автономное веб-приложение с домашними иконками и заставкой

Вам нужно сделать небольшой "хак" для скрипта PwaCompat и в вашем метатеге "манифест", заменив имя метатега на любой идентификатор, например, в вашем index.html:

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

manifest.json содержит ваше стандартное объявление manifest.json с названием, значками и стилем вашего веб-приложения.

js/pwacompat.js, содержит копию pwacompat.js из Google, с этой небольшой модификацией (строка 36):

Изменить:

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

по

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

где pwa-setup - это имя, которое вы помещаете в метатег, и это все, вы интерпретируете ваш manifest.json и перенаправление oauth в том же автономном контексте 🎉

ОБНОВЛЕНИЕ: Начиная с IOS 13 и выше, этот обходной путь больше не требуется. В любом случае, если вы хотите сохранить совместимость с IOS & lt; 13, вы можете использовать следующий скрипт для проверки версии IOS и определения условий использования:

<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>

Ответ 2

Хорошее решение на данный момент - взломать его через pwacompat. Но на Android изменение атрибута manifest rel на "pwa-setup" не соответствует требованиям веб-приложения, поэтому всплывающее окно установки на дом не появляется.

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

Измененная строка # 36

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

Лучшее решение - определить, отображается ли веб-приложение на iOS или Android, а затем изменить атрибут rel в "среде выполнения".

<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>

Ответ 3

Я объединил ответ @Lester с @Roysh и еще несколькими, чтобы сделать его более заменимым в PWA на iOS. Поскольку он потерял манифест, он будет использовать заголовок в качестве имени по умолчанию и теперь откроет текущий путь вместо start_url из манифеста.

<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>