在渐进式网络应用中重定向到Google OAuth流程

Jak*_*rsh 16 javascript oauth google-oauth progressive-web-apps

我一直在使用React和Next.js开发应用程序,目前正在添加PWA支持.

用户通过Google OAuth流程登录该应用.我最初使用的是JS客户端,它使用弹出窗口,但在PWA中遇到了错误.我现在通过将用户重定向到Google的OAuth网址来使用正常的OAuth流程.

这在浏览器中工作正常.在iOS上的独立PWA中,它会在新的Safari窗口中打开OAuth页面.这意味着OAuth流程在Safari中执行,最后用户在Safari中使用应用程序而不是独立的PWA.

我正在使用这种方法重定向:

export function setHref(newLocation: string) {
  window.location.href = newLocation;
}
Run Code Online (Sandbox Code Playgroud)

这甚至看起来是每个人都建议在重定向PWA时避免弹出窗口的方法.这最近改变了吗?或者是否有另一种方法可以在独立的渐进式Web应用程序中执行重定向/ OAuth流程?

Jor*_*ert 19

我有一个解决方法,解决ios safari独立Web应用程序上的oauth重定向问题.

问题是清单元标记,似乎webkit(safari)用旧规范实现它(Chromium有相同的问题并在最近的版本中修复它).

我通过修改您可以使用的Google的PWACompat Javascript来解决这个问题:

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

PWAcompat js可用于生成正确的html元标记,以便拥有一个带有主页图标和启动画面的独立Web应用程序

你需要在PwaCompat脚本和"manifest"元标记中做一个小的"hack",方法是用任何标识符替换元标记的名称,例如,在你的index.html中:

<link rel="pwa-setup" href="manifest.json" >
<script async src="js/pwacompat.js"></script>
Run Code Online (Sandbox Code Playgroud)

manifest.json包含您的标准manifest.json声明,其中包含您的Web应用程序的名称,图标和样式.

js/pwacompat.js,包含来自谷歌的pwacompat.js的副本,这个小修改(第36行):

变化:

const manifestEl = document.head.querySelector('link[rel="manifest"]');
Run Code Online (Sandbox Code Playgroud)

通过

const manifestEl = document.head.querySelector('link[rel="pwa-setup"]');
Run Code Online (Sandbox Code Playgroud)

其中pwa-setup是您放置在元标记上的名称,就是这样,您可以在同一个独立的上下文中解析manifest.json和oauth重定向


Les*_*ter 7

现在,一个好的解决方案是通过pwacompat对其进行破解。但是在Android上,将manifest rel属性更改为“ pwa-setup”并不符合webapp的要求,因此不会显示安装到主弹出窗口。

<link rel="pwa-setup" href="manifest.json" >
<script async src="js/pwacompat.js"></script>
Run Code Online (Sandbox Code Playgroud)

更改第36

const manifestEl = document.head.querySelector('link[rel="pwa-setup"]');
Run Code Online (Sandbox Code Playgroud)

更好的解决方案是确定Web应用程序是在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>
Run Code Online (Sandbox Code Playgroud)