Instagram oAuth 身份验证 postMessage 问题仅适用于移动浏览器

Instagram oAuth Authentication postMessage issue only with Mobile Browsers

我有一个 Ionic 2 应用程序 ("native"),它也可以在移动设备和桌面浏览器的浏览器上运行。 此应用程序通过 Instagram、Google、Facebook 和 Twitter 提供身份验证。 在 API 方面,这是由 hapi.jsbell 插件处理的。

现在,我在移动浏览器上进行 Instagram 身份验证时遇到了一个问题。

当此应用程序在浏览器上运行而不是依赖于 Ionic 提供的身份验证机制时,我们已经实现了 "browser" 回退来做到这一点。

除了 Instagram 之外,我们在任何实施方面都没有遇到重大问题,Instagram 之前运行良好。

我们有这段代码应该打开一个新的 window(浏览器上的选项卡)来处理社交网络登录页面,当我们取回授权令牌时,然后继续关闭选项卡并在应用程序上验证用户。

在应用程序端,处理此选项卡切换和通信行为基本上如下所示:

private requestToken(tokenEndpoint, resolve, reject) {
    let messageReceived = false;
    let win = window.open(this.globals.BASE_URL + tokenEndpoint,
        '_blank', 'toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=no, copyhistory=no, width=500, height=300');

    // Await auth message
    window.onmessage = (e) => {
        let credentials;
        messageReceived = true;

        try {
            credentials = JSON.parse(e.data);
        }
        catch (error) {
            credentials = e.data;
        }

        return credentials ? resolve(credentials) : reject();
    };

    let interval = window.setInterval(() => {
        try {
            // win is already null after closing first tab
            if (win == null || win.closed) {
                window.clearInterval(interval);

                if (!messageReceived) {
                    reject();
                }
            }
        }
        catch (e) { }
    }, 1000);
}

我的 API 将 return 所需的数据发送到前端:

<script>window.opener.postMessage('{0}', '*');window.close();</script>

,其中 {0} 是我需要的身份验证数据。

对于任何其他社交网络,这将打开一个地址为 about:blank 的新选项卡,然后将更改为正确的 url 以输入 username/password。完成后,服务器会返回那个小脚本,phone 会关闭选项卡,将数据传回应用程序。它运行完美。

然而,

对于 Instagram,行为有所不同。将打开一个新选项卡,它会立即关闭并出现一个新选项卡,我将在其中输入我的数据。 问题是,当服务器返回脚本时,我的 window.opener 为空并且对原始页面的引用丢失,这使我无法取回身份验证数据。

我该如何克服这个问题?我怎样才能强制原来的选项卡不关闭,而是像其他选项卡一样运行,只导航到 IG 登录页面? IG 是否发回 301 或 302 回复?如果是的话,我到现在都抓不到。

对于那些最终出现在这里的人,解决方案是使用 window.parent.parent.postMessage() 而不是依赖 window.opener.postMessage()