我正在开展一些Chrome扩展程序。谷歌开发者控制台已经配置好并且最终使用了gapi,但是我已经遇到了问题,比如用户体验。
所以这是我尝试实现的情景:
这种作品。我得到了要求许可的弹出窗口,我单击“接受”,然后popus变为空白,标题设置为"正在连接..." (不会关闭)并且永远不会触发回调函数。
我知道访问被授予,因为当我单击“接受并重新加载”页面时,它可以使用immediate:true进行授权,并且我的扩展程序可以正常工作。
我检查了几个问题,主题和问题,在Google搜索答案时询问了不同的查询,我找到了这个解决方案:
所以这里有一些代码(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");
}
}
}
}
任何提示,链接或解决方案都会被贬低。
答案 0 :(得分:2)
好的,这就是我为OAuth2所做的工作。
场景如下:
首先,我需要解释为什么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);
}
}
希望有人能利用这一点。我知道我花了太多时间在这上面。