很抱歉,是否曾经有人问过这个问题,但是我整天都在搜寻Google,但是没有任何结果。
我正在为Chrome扩展程序使用Chrome Identity API(我正在为我的工作而构建(与Google Sheets API进行交互),并且我希望保留用户的登录信息,但是使用该API刷新令牌无处可去被发现。
我首先实现了chrome.identity.getAuthToken()
,并且能够将请求授权给gSheets API,但访问令牌过期时出现了问题。我知道,如果您使用getAuthToken()
调用令牌,则再次调用interactive: false
会刷新令牌,但前提是您登录时使用的People拥有与初始授权相同的电子邮件与弹出窗口进行交互,而这并不是我想要的,这仅仅是因为在浏览器中我已记录了我的个人电子邮件,并且我希望对该扩展程序的工作电子邮件进行授权。因此,一小时后,我需要请求一个新令牌,该令牌将提示登录弹出窗口,这是糟糕的用户体验。
然后,我尝试使用chrome.identity.launchWebAuthFlow()
和终结点https://accounts.google.com/o/oauth2/v2/auth,知道launchWebAuthFlow()
适用于非Google帐户,尽管据我所知,即使运行良好,也没有假设在45分钟后刷新令牌的一种方法,以避免踢出用户。
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
switch (request.type) {
case "login":
let authURL = "https://accounts.google.com/o/oauth2/v2/auth";
const clientId = `<CLIENT_ID>`;
const redirectURL = chrome.identity.getRedirectURL("oauth2");
const auth_params = {
client_id: clientId,
redirect_uri: redirectURL,
response_type: "token",
scope: "https://www.googleapis.com/auth/spreadsheets"
};
const paramString = Object.keys(auth_params)
.map(function(k) {
return k + "=" + auth_params[k];
})
.join("&");
authURL += "?" + paramString;
chrome.identity.launchWebAuthFlow(
{ url: authURL, interactive: true },
function(responseURL) {
if (chrome.runtime.lastError) {
console.log(chrome.runtime.lastError);
return;
}
if (responseURL) {
const paramsString = responseURL.substring(
responseURL.indexOf("#") + 1
);
const params = new URLSearchParams(paramsString);
const paramsObj = () => {
const obj = {};
for (var entry of params.entries()) {
obj[entry[0]] = entry[1];
}
return obj;
};
const { access_token } = paramsObj();
sendResponse({
access_token
});
} else {
console.log(`${responseURL} defined?`);
}
}
);
return true;
default:
console.log("placeholder");
break;
}
});
如果愿意改善用户体验,我愿意放弃Chrome Identity API并使用其他OAuth2流程。
TL; DR:我希望在上一个令牌过期前几分钟,通过Chrome Identity API或任何其他OAuth2实现获取一个新的访问令牌,同时能够使用不同于已登录Chrome的Google帐户(人)。
答案 0 :(得分:1)
通过代码获取新令牌是错误的方式。相反,刷新令牌旨在在旧令牌过期后获取新令牌。
交换刷新和访问令牌的代码。
https://developers.google.com/identity/protocols/oauth2/web-server?hl=en#exchange-authorization-code
保存刷新令牌。当前访问令牌过期时,通过刷新令牌获取新令牌。
https://developers.google.com/identity/protocols/oauth2/web-server?hl=en#offline
祝编码顺利。
答案 1 :(得分:0)
我可以编辑上一个问题,但我将回答它:
有一种方法可以通过发出代码而不是使用令牌来获取新令牌
access_type=offline
和response_type:'code'
。
let authURL = 'https://accounts.google.com/o/oauth2/v2/auth';
const redirectURL = chrome.identity.getRedirectURL("oauth2");
const auth_params = {
client_id: clientId,
redirect_uri: redirectURL,
response_type: 'code',
access_type: 'offline',
scope: 'https://www.googleapis.com/auth/spreadsheets',
};
chrome.identity.launchWebAuthFlow({url: authURL, interactive: true}, responseURL => console.log(responseURL))
响应将是一个URL:
https://<extension_id>.chromiumapp.org/oauth2?code=4/A<code>#
返回的代码可以兑换为只能使用1次的令牌。然后,您将POST请求发送到https://www.googleapis.com/oauth2/v4/token
,并以以下代码段作为请求:
POST /oauth2/v4/token HTTP/1.1
Host: www.googleapis.com
Content-Type: application/x-www-form-urlencoded
code=4/A<code>&
client_id=your_client_id&
client_secret=your_client_secret&
redirect_uri=https://<extension_id>.chromiumapp.org/oauth2&
grant_type=authorization_code
响应将是一个JSON对象,您可以使用它约1个小时向Google API发出请求:
{
"access_token": "<access_token>",
"token_type": "Bearer",
"expires_in": 3578
}
最后,在访问令牌过期之前,您可以使用launchWebAuthFlow()
调用interactive: false
,它将返回一个新代码,并获得一个新令牌。