[英]Why gapi.auth.authorize with “immediate: false” doesn't close popup and fire callback?
我正在開發一些擴展名。 Google開發人員控制台已配置完畢,並且最終可以使用gapi進行工作,但是,例如UX,我遇到了問題。
所以這是我要實現的方案:
而這種作品。 我得到要求許可的彈出窗口,單擊“接受”,但是彈出窗口變為空白,標題設置為“ Connecting ...”(未關閉),並且永遠不會觸發回調函數。
我知道訪問是被授予的,因為當我單擊接受並重新加載頁面時,它可以使用Instant: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");
}
}
}
}
任何提示,鏈接或解決方案都將受到重視。
好的,這是使OAuth2正常工作的方法。
場景如下:
首先,我需要解釋為什么launchWebAuthFlow不能更早地工作。 如前所述,我配置了Google Developers Console,並為Chrome應用程序創建了密鑰和客戶端ID。 這對於launchWebAuthFlow是錯誤的。 它應該是具有配置的重定向URL的Web應用程序。
在chrome擴展程序中,這是獲取重定向URL的方法: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);
}
}
希望有人會利用這一點。 我知道我花了太多時間在此上。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.