我正在开发一些扩展名。 Google开发人员控制台已配置完毕,并且最终可以使用gapi进行工作,但是,例如UX,我遇到了问题。
所以这是我要实现的方案:
尝试使用登录的Google Chrome进行身份验证。
如果失败,请尝试通过gapi.auth.authorize进行即时身份验证:true。
如果失败,请尝试通过gapi.auth.authorize进行即时身份验证:false。
而这种作品。我得到要求许可的弹出窗口,单击“接受”,但是弹出窗口变为空白,标题设置为“ Connecting ...”(未关闭),并且永远不会触发回调函数。
我知道访问是被授予的,因为当我单击接受并重新加载页面时,它可以使用Instant:true进行授权,并且我的扩展程序可以正常工作。
我在Google搜索了几个问题,主题和问题并询问了不同的查询以寻找答案,然后发现了以下解决方案:
setTimeout(checkAuth,1)-尝试过,没有成功。
我推论不能在即时:真之后立即调用即时:假,因此我尝试一下,并尝试首先使用即时:假进行身份验证。结果相同。
我尝试添加gapi.auth.init,并在其回调中检查Author(也使用setTimeout)。
因此,这里是一些代码(background.js)。抱歉,看起来像意大利面条,我是JS的初学者。
function respond(interactive, sendResponse) {
xhrWithAuth('GET',
'https://www.googleapis.com/gmail/v1/users/me/profile',
interactive, // false
onUserMailFetched, sendResponse);
function xhrWithAuth(method, url, interactive, callback, sendResponse) {
var access_token;
var retry = true;
getToken();
// 1. trying to use Chrome user
function getToken() {
chrome.identity.getAuthToken({
interactive: interactive
}, function (token) {
if (chrome.runtime.lastError) {
// 2. here lastError is User is not signed in. Calling onUserMailFetched
callback(chrome.runtime.lastError, null, null, sendResponse);
}
access_token = token;
requestStart();
});
}
// I guess not important in topic
function requestStart() {
var xhr = new XMLHttpRequest();
xhr.open(method, url);
xhr.setRequestHeader('Authorization', 'Bearer ' + access_token);
xhr.onload = requestComplete;
xhr.send();
}
// I guess not important in topic
function requestComplete() {
if (this.status == 401 && retry) {
retry = false;
chrome.identity.removeCachedAuthToken({
token: access_token
},
checkAuth_neverCalled);
} else {
callback(null, this.status, this.response, sendResponse);
}
}
// I guess not important in topic
function checkAuth_neverCalled() {
console.log("checking auth when getAuthToken fails");
gapi.auth.authorize({
client_id: OAUTH2_CLIENT_ID,
scope: OAUTH2_SCOPES,
immediate: false
}, handleAuthResult);
// Handle the result of a gapi.auth.authorize() call.
function handleAuthResult(authResult) {
console.log("authenticated: ", authResult);
if (authResult) {
// do something with data
} else {
consoel.log("failed");
}
}
}
}
// This is important part.
function onUserMailFetched(error, status, response, sendResponse) {
if (!error && status == 200) {
// do something with data
} else {
// 3. as we have error at first call, we checkAuth with immediate = true
setTimeout(function () {
checkAuthWhenNotLogged(sendResponse, true);
}, 10);
}
}
// This is important part.
function checkAuthWhenNotLogged(sendResponse, immediateVal) {
gapi.auth.authorize({
client_id: OAUTH2_CLIENT_ID,
scope: OAUTH2_SCOPES,
immediate: immediateVal
}, handleAuthResult);
// Handle the result of a gapi.auth.authorize() call.
// 5. But this function is never called again (when called with false).
function handleAuthResult(authResult) {
if (authResult) {
// 4. and this is called when checkAuth with true fail. We call checkAuth (itself) with false.
if (authResult.error == "immediate_failed") {
gapi.auth.init(function () {
setTimeout(function () {
checkAuthWhenNotLogged(sendResponse, false);
}, 10);
});
} else {
// yay, we are authneticated and can call gmail service
gapi.client.load('gmail', 'v1', function () {
var request = gapi.client.gmail.users.getProfile({
'userId': 'me'
});
request.execute(function (profile) {
// do something with data
});
});
}
} else {
console.log("failed");
}
}
}
}
任何提示,链接或解决方案都将受到重视。
最佳答案
好的,这是使OAuth2正常工作的方法。
场景如下:
尝试使用Google Chrome登录用户进行身份验证。
如果失败,请尝试通过gapi.auth.authorize进行即时身份验证:true。
如果失败,请尝试使用chrome.identity.launchWebAuthFlow
首先,我需要解释为什么launchWebAuthFlow不能更早地工作。如前所述,我配置了Google Developers Console,并为Chrome应用程序创建了密钥和客户端ID。这对于launchWebAuthFlow是错误的。它应该是具有配置的重定向URL的Web应用程序。
在chrome扩展程序中,这是如何获取重定向网址的方法:
var redirectURL = chrome.identity.getRedirectURL(“ suffix”);
它将创建如下内容:
https:// {appId} .chromiumapp.org /
您需要在客户端ID配置中将此设置为重定向链接。就我而言,我必须在js代码中更改已使用的客户端ID。
这是对我有用的代码:
(...)
var redirectURL = chrome.identity.getRedirectURL();
var options = {
'interactive': true,
url: 'https://accounts.google.com/o/oauth2/auth?' +
'scope=profile email' +
'&response_type=token' +
'&client_id=' + OAUTH2_CLIENT_ID_WEB +
'&redirect_uri=' + redirectURL
}
chrome.identity.launchWebAuthFlow(options, function (redirectUri1) {
if (chrome.runtime.lastError) {
console.log(chrome.runtime.lastError);
} else {
// redirectUri is a link with access_token param inside, we need to extract it
var paramName = "access_token"
var results = new RegExp(paramName + '=([^&#]*)').exec(redirectUri1);
if (results == null) {
console.log("not found");
} else {
console.log(results[1] || 0);
access_token = results[1]; // here we set the token
requestStart(); // here I launch google api request
}
};
});
(...)
function requestStart() {
// url = 'https://www.googleapis.com/plus/v1/people/me'
// method = 'GET'
var xhr = new XMLHttpRequest();
xhr.open(method, url);
xhr.setRequestHeader('Authorization', 'Bearer ' + access_token);
xhr.onload = requestComplete;
xhr.send();
}
function requestComplete() {
if (this.status == 401 && retry) {
retry = false;
chrome.identity.removeCachedAuthToken({
token: access_token
},
checkAuth);
} else {
callback(this.status, this.response);
}
}
希望有人会利用这一点。我知道我花了太多时间在此上。