перенаправление на поток 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>