gpt4 book ai didi

javascript - 为什么带有 "immediate: false"的 gapi.auth.authorize 不关闭弹出窗口并触发回调?

转载 作者:行者123 更新时间:2023-11-30 17:13:51 26 4
gpt4 key购买 nike

我正在开发一些 chrome 扩展程序。 Google Developer Console 已配置并使用 gapi 最终可以正常工作,但我遇到了问题,比方说,UX。

这是我要实现的场景:

  1. 尝试使用 Google Chrome 登录用户进行身份验证。
  2. 如果失败,尝试通过 gapi.auth.authorize 进行身份验证,立即执行:true。
  3. 如果失败,尝试通过 gapi.auth.authorize 立即验证:false。

还有这种作品。我收到请求许可的弹出窗口,我单击“接受”,但随后 popus 变为空白,标题设置为“正在连接...”(不关闭)并且永远不会触发回调函数。

我知道访问已被授予,因为当我单击接受并重新加载页面时,它可以使用 immediate:true 进行授权,并且我的扩展程序完美运行。

我检查了几个问题、主题和问题,在谷歌中搜索不同的查询来寻找答案,我找到了这个解决方案:

  1. setTimeout(checkAuth, 1) - 尝试过,没有成功。
  2. 我推断不能在 immediate:true 之后立即调用 immediate:false,所以我尝试了一下,并尝试首先使用 immediate:false 进行身份验证。结果相同。
  3. 我尝试添加 gapi.auth.init,并在其回调中检查 Auth(也使用 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 正常工作所做的工作。

场景如下:

  1. 尝试使用 Google Chrome 登录用户进行身份验证。
  2. 如果失败,尝试通过 gapi.auth.authorize 进行身份验证,立即执行:true。
  3. 如果失败,尝试使用 chrome.identity.launchWebAuthFlow

首先,我需要解释为什么 launchWebAuthFlow 之前没有工作。正如我提到的,我配置了 Google Developers Console 并为 Chrome 应用程序创建了 key 和客户端 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);
}
}

希望有人能利用这一点。我知道我在这上面花了太多时间。

关于javascript - 为什么带有 "immediate: false"的 gapi.auth.authorize 不关闭弹出窗口并触发回调?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26481709/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com