Zed_Blade Zed_Blade - 1 year ago 119
Javascript Question

Instagram oAuth Authentication postMessage issue only with Mobile Browsers

I have an Ionic 2 app ("native") that also runs on the browser for both mobile devices and desktop browsers.
This app provides authentication via Instagram, Google, Facebook and Twitter.
On the API side this is handled by

hapi.js
and the
bell
plugin.

Now, I've been fighting an issue with Authentication on Instagram when doing it on a mobile browser.

When this app runs on the browser instead of relying on the Ionic provided auth mechanisms we've implement our "browser" fallbacks to do it.

We've been having no major issues with any of the implementations other than Instagram, which was previously working just fine.

We have this code that is supposed to open a new window (tab on the browser) to deal with the social network login page and when we get back the auth token then proceed to close the tab and authenticate the user on the app.

On the app side, handling this tab switch and communications behaviour looks essentially like this:

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);
}


My API will return the required data to the frontend with:

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


, where
{0}
is my required auth data.

For any other social network, this will open a new tab with address
about:blank
and will then change to the correct
url
for inputting the username/password. When that's done, the server hits back with that little script and the phone closes the tab passing the data back to the app. It works flawlessly.

HOWEVER,



For Instagram the behaviour is different. A new tab will open, it will close immediately and a new one will appear, where I'll input my data back.
The problem is that by the time the server gets back with the script my
window.opener
is null and a reference to the original page is lost which prevents me from getting the auth data back.

How can I overcome this? How can I force the original tab to not close but rather behave as the other ones and just navigate to the IG login page?
Does IG send back a 301 or 302 reply? If it does, I've been unable to catch it so far.

Answer Source

For those that end up here, the solutions was to use window.parent.parent.postMessage() rather than rely on window.opener.postMessage()

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download