Google oauth not closing login page in mobile devices.

  • 1
  • Problem
  • Updated 4 years ago
When the user clicks on Google Sign in button, another window opens and they sign in. In simulator everything works great but in mobile devices the second window opens and after the user logs in, Google doesn't close the login window so the user ends up staring at an empty page. In other words the callback function never gets called because the mobile browser doesn't close the new (login) window. Is there a way to work around this issue?
Photo of Anandh Krishnan

Anandh Krishnan

  • 9 Posts
  • 0 Reply Likes

Posted 4 years ago

  • 1
Photo of Petra V.

Petra V., Champion

  • 7794 Posts
  • 1391 Reply Likes
When the user clicks on Google Sign in button, another window opens
Why? And how? A mobile device usually doesn't have 'another window' in the webview.
Photo of Anandh Krishnan

Anandh Krishnan

  • 9 Posts
  • 0 Reply Likes
I want to store some info in google spreadsheet. To do this, I will have to get Oauth token. So have written the code as below,

var authURI = 'https://accounts.google.com/o/oauth2/...';
var tokenURI = 'https://accounts.google.com/o/oauth2/...';
var redirectURI = 'http://www.mocky.io/v2/5734bee3130000...';
var phonegapi = {};

(function() {
var loginWindow;

/*
* Config for google authentication. The same for all apps
*/
var gapiConfig = {
auth_uri: authURI,
token_uri: tokenURI,
redirect_uri: redirectURI
};

var logJSON = function(mess, json) {
console.log(mess + json ? JSON.stringify(json, null, 2) : '');
};

/*
* Authentication/Authorization is a 3 step process:
* 1 Open a browser and navigate to a URI with a URI that requests authentication
* 2 Catch every time the browser changes URI and watch for a URI that contains a code
* 3 When the code is received exchange the code for tokens
*/

/*
* Step 1: Open a browser on a login page
*/
var openLogin = function(params) {
// open Cordova inapp-browser with login page
// Pass in app info
var login_uri = gapiConfig.auth_uri
+ '?client_id=' + params.client_id
+ '&redirect_uri=' + gapiConfig.redirect_uri
+ '&response_type=code'
+ '&scope=' + params.scope;
loginWindow = window.open(login_uri, '_blank', 'location=yes');
loginWindow.addEventListener('loadstop', function(event) {
setTimeout(function(){},300);
onLoadStop(event, params);
});

};

/*
* Step 2: Catch the URI changes in the login browser
*/
var onLoadStop = function(e, params) {
logJSON('onLoadStart');
// var url = e.originalEvent.url;
var url = e.url;
// alert('url-->'+url);
var code = /\?code=(.+)$/.exec(url);
var error = /\?error=(.+)$/.exec(url);
if (code || error){
// when everything matches
loginWindow.close();

}

if (code) {
getTokens(code[1], params);

} else if (error) {
logJSON('error: ' + error);
params.callback('login failed: ' + error);
}
};

/*
* Step 3: Exchange the authorization code for access/refresh tokens
*/
var getTokens = function(code, params) {
logJSON('getTokens: ' + code);
$.ajax({
url: gapiConfig.token_uri,
data: {
code: code,
client_id: params.client_id,
client_secret: params.client_secret,
redirect_uri: gapiConfig.redirect_uri,
grant_type: 'authorization_code'
},
type: 'POST',
dataType: 'json',
success: function(data){
// got access_token
var tokens = data;
logJSON('tokens received: ', tokens);
gapi.auth.setToken(tokens);
params.callback(null, tokens);
},
error: function(error){
// could not get token
params.callback('login failed: ' + error);
}
});
};

})();

Here opening the page as

loginWindow = window.open(login_uri, '_blank', 'location=yes');

to get the token.

and closing as

if (code || error){
// when everything matches
loginWindow.close();

}

But window doesn't close.
Photo of Petra V.

Petra V., Champion

  • 7794 Posts
  • 1391 Reply Likes
But window doesn't close.
- is object 'loginWindow' defined after calling window.open()?
[btw: it would be better to use cordova.InAppBrowser.open()]
- is the line 'loginWindow.close();' reached at all?
- I don't see function openLogin be called anywhere. Am I missing some code?
Photo of Anandh Krishnan

Anandh Krishnan

  • 9 Posts
  • 0 Reply Likes
Yes. It is reaching the line loginWindow.close();

I am calling the function openLogin from other file.
Photo of Petra V.

Petra V., Champion

  • 7794 Posts
  • 1391 Reply Likes
1. So, how are you making sure that the variable loginWindow is defined in this file?
2. Why don't you use a plugin for oAuth, like https://www.npmjs.com/package/cordova... ?
Photo of Anandh Krishnan

Anandh Krishnan

  • 9 Posts
  • 0 Reply Likes
Object is created for loginWindow.
Confirmed by alert(loginWindow) command.

New to this...let me check
https://www.npmjs.com/package/cordova...
Photo of Petra V.

Petra V., Champion

  • 7794 Posts
  • 1391 Reply Likes
Object is created for loginWindow.
But does the object have the method 'close()', or is it a newly created object and not a reference to the opened window?
Photo of Anandh Krishnan

Anandh Krishnan

  • 9 Posts
  • 0 Reply Likes
The existing code works fine on My Eclipse2015 simulator...but it is not in mobile device...
Photo of Petra V.

Petra V., Champion

  • 7794 Posts
  • 1391 Reply Likes
In that case: do you really get an inAppBrowser window?
Is your inAppBrowser plugin active (as in: did you wait for the deviceready event before attempting to do cordova InAppBrowser.open())?
Photo of Anandh Krishnan

Anandh Krishnan

  • 9 Posts
  • 0 Reply Likes
Not used inAppBrowser window.

Have done below changes for using inAppBrowser window in my existing code.
Please correct me if I am wrong here.

1. Added the plugin in config.xml as

2. index.js

document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
window.open = cordova.InAppBrowser.open;
}

i
Photo of Petra V.

Petra V., Champion

  • 7794 Posts
  • 1391 Reply Likes
1. If you want to post code here, wrap it in an html CODE element as described under "some HTML allowed".

2. The above code in onDeviceReady doesn't guarantee the the event fired before you attempt to open that login window. You must make correct use of callback functions, otherwise the order of code parts execution is not defined, due to the asynchronous nature of javascript.
Photo of Anandh Krishnan

Anandh Krishnan

  • 9 Posts
  • 0 Reply Likes
Tried with inAppBrowser. But no help...

can anyone please help me on this....
Photo of Petra V.

Petra V., Champion

  • 7794 Posts
  • 1391 Reply Likes
I'm out.
In this short thread, you have ignored three of my questions.
Photo of Anandh Krishnan

Anandh Krishnan

  • 9 Posts
  • 0 Reply Likes
Yes... Moved the code cordova.InAppBrowser.open in the callback function.

Calling the close method on the newly created window.

Please let me know if i answered for all your questions...