我有一个PWA
应用程序,需要通过Facebook/OAuth
进行用户身份验证。
问题在于OAuth
机制在iPhone/Standalone
以外的所有情况下都可以使用。
我需要找出某种方法来使PWA
上的Facebook/OAuth
应用程序与iPhone
一起使用。可能吗? Yes
/ No
?
我创建了一个示例项目:
https://github.com/napolev/pwa-oauth-login
根据文章
为简单起见,在此示例项目中,我将Facebook/OAuth
机制替换为简单的Custom/OAuth
机制。
index.html
<script>
...
window.open(
url_oauth + '?url_callback=' + encodeURIComponent(url_callback),
'Login Flow',
'width=350,height=250'
);
...
window.addEventListener('message', function (e) {
token.innerText = e.data.token;
})
...
</script>
...
<div>
Token: <span id="token">...</span>
</div>
callback.html
<script type="text/javascript">
// redirected to this page from the OAuth page
...
var data = {
token: ...,
};
window.opener.postMessage(data, ...);
window.close();
...
</script>
如果将我的Mac
连接到我的iPhone
并执行Remote Debugging
,我可以看到当上述方法window.close();
被调用时,它会抛出以下警告,这让我对自己的可能性感到非常悲观:
由于JavaScript未打开窗口,因此无法关闭
关于通话:window.opener.postMessage(...)
是另一个故事,目前我没有足够的信息了解为什么不发送
令牌打开窗口。可能是因为与window.close();
类似的问题。
我进行了一系列实验,所有实验都很好,但是情况:iPhone/Standalone
失败了,因为即使添加了快捷方式
成功返回到主屏幕,并且当您单击时,该应用会正确打开而没有地址栏
按钮:Start OAuth flow
将打开一个新窗口,这次带有地址栏(github.io
)。然后,当用户点击
链接:[APP-CALLBACK]
,将用户重定向到应用回调网址,但此窗口不会将令牌发送回打开器
窗口,它也不会关闭。如果我在Android/Standalone
上进行了此实验,那么效果很好。最重要的是,在同一
iPhone
与Safari
(但不是独立的)一起使用时,它可以正常工作。如您所见,我面临的唯一问题是iPhone/Standalone
在以下动画图像上。
请检查下面的Experiments
部分以获取更多详细信息。
$ git clone https://github.com/napolev/pwa-oauth-login
$ cd pwa-oauth-login
$ npm i
$ npm run start
在您的iPhone
(同一网络上的另一台设备)上,转到:
http://[YOUR-SERVER-IP-ADDRESS]:4000
Android / Google Chrome -单击突出显示的选项以独立安装应用程序。
iPhone / Safari -单击突出显示的图标以独立安装该应用程序。
1- 2018-11-24 00:10 GMT
。在此提交上,OAuth
流的行为如下:
Windows + Chrome → SUCCESS
Windows + Firefox → SUCCESS
Windows + Edge → SUCCESS
Android + Chrome → SUCCESS
Android + Standalone → SUCCESS
Mac + Chrome → SUCCESS
Mac + Safari → SUCCESS
iPhone + Chrome → SUCCESS
iPhone + Safari → SUCCESS
iPhone + Standalone → !!! FAILURE !!!
答案 0 :(得分:1)
使用服务器端代理怎么办,这样PWA永远不会离开其作用域,并且服务器会在后台完成所有OAuth工作?
https://medium.com/@madumalt/oauth2-proxy-for-single-page-applications-8f01fd5fdd52
答案 1 :(得分:1)
如此处所述,在将应用程序加载到iOS设备上时删除清单。
var iOS = !!navigator.platform && /i(Phone|Pad|Pod)/.test(navigator.platform);
if (iOS) {
document.querySelector('link[rel="manifest"]').setAttribute("rel", "no-on-ios");
}