我尝试在 Phonegap 2.9.0 应用程序中实现 Google OAuth 2 身份验证。根据这篇博文,我设法打开了授权同意页面,获取代码,发布它以获取访问令牌。如果我不关闭 InAppBrowser 窗口,它会起作用。
问题是当我调用时authWindow.close()
,Eclipse LogCat 中会显示以下错误:
08-11 07:54:10.588: I/Web Console(803): Close Windows at file:///android_asset/app/js/oauth2.js:121
08-11 07:54:10.648: I/Web Console(803): processMessage failed: Message: S11 InAppBrowser938825912 {"type":"loadstart","url":"http:\/\/localhost\/?code=4\/QxgCmz53B2eksAGCS8qsF.otg5rhswx00QOdsfdsfsdfl05ti8ZT3bTmXfagAI"} at file:///android_asset/app/js/lib/cordova.js:980
08-11 07:54:10.658: I/Web Console(803): processMessage failed: Error: Error: Error calling method on NPObject. at file:///android_asset/app/js/lib/cordova.js:981
08-11 07:54:10.728: I/Web Console(803): processMessage failed: Stack: Error: Error calling method on NPObject.
08-11 07:54:10.728: I/Web Console(803): at androidExec (file:///android_asset/app/js/lib/cordova.js:863:48)
08-11 07:54:10.728: I/Web Console(803): at Object.close (file:///android_asset/app/js/lib/cordova.js:3336:9)
08-11 07:54:10.728: I/Web Console(803): at Object.<anonymous> (file:///android_asset/app/js/oauth2.js:123:30)
08-11 07:54:10.728: I/Web Console(803): at Object.<anonymous> (file:///android_asset/app/js/lib/jquery-2.0.3.js:4676:9)
08-11 07:54:10.728: I/Web Console(803): at [object Object].<anonymous> (file:///android_asset/app/js/lib/jquery-2.0.3.js:4360:28)
08-11 07:54:10.728: I/Web Console(803): at [object Object].fire (file:///android_asset/app/js/lib/cordova.js:709:23)
08-11 07:54:10.728: I/Web Console(803): at Object._eventHandler (file:///android_asset/app/js/lib/cordova.js:3332:39)
08-11 07:54:10.728: I/Web Console(803): at file:///android_asset/app/js/lib/cordova.js:3376:12
08-11 07:54:10.728: I/Web Console(803): at Object.callbackFromNative (file:///android_asset/app/js/lib/cordova.js:301:54)
08-11 07:54:10.728: I/Web Console(803): at processMessage (file:///android_asset/app/js/lib/cordova.js:975:21) at file:///android_asset/app/js/lib/cordova.js:982
授权方式:
oauth2.authorize = function(options) {
var deferred = $.Deferred();
// Build the OAuth consent page URL
var authUrl = 'https://accounts.google.com/o/oauth2/auth?' + $.param({
client_id: options.client_id,
redirect_uri: options.redirect_uri,
response_type: 'code',
scope: options.scope
});
// Open the OAuth consent page in the InAppBrowser
var authWindow = window.open(authUrl, '_blank', 'location=no,toolbar=no');
// The recommendation is to use the redirect_uri
// "urn:ietf:wg:oauth:2.0:oob"
// which sets the authorization code in the browser's title.
// However, we can't
// access the title of the InAppBrowser.
//
// Instead, we pass a bogus redirect_uri of "http://localhost",
// which means the
// authorization code will get set in the url. We can access the
// url in the
// loadstart and loadstop events. So if we bind the loadstart
// event, we can
// find the authorization code and close the InAppBrowser after
// the user
// has granted us access to their data.
$(authWindow).on('loadstart', function(e) {
console.log('loadStart callback');
var url = e.originalEvent.url;
console.log(url);
var code = /\?code=(.+)$/.exec(url);
console.log('Code = ' + code);
var error = /\?error=(.+)$/.exec(url);
if (code) {
console.log('process Code');
// Exchange the authorization code for an access token
$.post('https://accounts.google.com/o/oauth2/token', {
code: code[1],
client_id: options.client_id,
client_secret: options.client_secret,
redirect_uri: options.redirect_uri,
grant_type: 'authorization_code'
}).done(function(data) {
console.log('DONE: ' + data);
deferred.resolve(data);
}).fail(function(response) {
console.log('FAIL: ' + response);
deferred.reject(response.responseJSON);
});
} else if (error) {
// The user denied access to the app
deferred.reject({
error: error[1]
});
}
if (code || error) {
console.log('Close Windwos');
// Always close the browser when match is found
authWindow.close();
}
console.log("Fin loadStart");
});
return deferred.promise();
};