用户使用 chrome.identity.launchWebAuthFlow 登录后,如何在过期之前获取新的访问令牌?

Ivo*_*vor 9 google-chrome google-chrome-extension

抱歉,如果之前有人问过这个问题,但我花了一整天的时间进行谷歌搜索,但没有任何结果。

\n\n

我正在为我的工作构建的 Chrome 扩展程序使用 Chrome Identity API(与 Google Sheets API 交互),并且我希望保留用户的登录信息,但无法使用此 API 刷新令牌被发现。

\n\n

我首先实现chrome.identity.getAuthToken()并能够授权对 gSheets API 的请求,当访问令牌过期时出现问题。我知道,getAuthToken()如果您使用 调用,再次调用会刷新令牌interactive: false,但前提是People具有您在与弹出窗口的初始交互中授权的相同电子邮件地址,而这不是我想要的只是因为在我的浏览器中我使用我的个人电子邮件登录,并且我想为扩展程序授权工作电子邮件。因此,1 小时后我需要请求一个新的令牌,这将提示登录弹出窗口,这是一种糟糕的用户体验。

\n\n

然后我尝试使用chrome.identity.launchWebAuthFlow()端点https://accounts.google.com/o/oauth2/v2/auth知道这launchWebAuthFlow()是针对非 Google 帐户的,尽管它运行良好,但据我所知,没有办法在 \xe2\x80\x94 后刷新令牌,假设 \xe2\x80\x94 45 分钟,以避免将用户踢出。

\n\n
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {\n  switch (request.type) {\n    case "login":\n      let authURL = "https://accounts.google.com/o/oauth2/v2/auth";\n      const clientId = `<CLIENT_ID>`;\n      const redirectURL = chrome.identity.getRedirectURL("oauth2");\n      const auth_params = {\n        client_id: clientId,\n        redirect_uri: redirectURL,\n        response_type: "token",\n        scope: "https://www.googleapis.com/auth/spreadsheets"\n      };\n\n      const paramString = Object.keys(auth_params)\n        .map(function(k) {\n          return k + "=" + auth_params[k];\n        })\n        .join("&");\n\n      authURL += "?" + paramString;\n\n      chrome.identity.launchWebAuthFlow(\n        { url: authURL, interactive: true },\n        function(responseURL) {\n          if (chrome.runtime.lastError) {\n            console.log(chrome.runtime.lastError);\n            return;\n          }\n\n          if (responseURL) {\n            const paramsString = responseURL.substring(\n              responseURL.indexOf("#") + 1\n            );\n            const params = new URLSearchParams(paramsString);\n\n            const paramsObj = () => {\n              const obj = {};\n              for (var entry of params.entries()) {\n                obj[entry[0]] = entry[1];\n              }\n              return obj;\n            };\n\n            const { access_token } = paramsObj();\n\n            sendResponse({\n              access_token\n            });\n          } else {\n            console.log(`${responseURL} defined?`);\n          }\n        }\n      );\n\n      return true;\n    default:\n      console.log("placeholder");\n      break;\n      }\n});\n
Run Code Online (Sandbox Code Playgroud)\n\n

如果这意味着我可以改善用户的用户体验,我愿意放弃 Chrome Identity API 并使用另一个 OAuth2 流程。

\n\n

TL;DR:我想在前一个令牌过期前几分钟通过 Chrome Identity API 或任何其他 OAuth2 实现获取新的访问令牌,同时能够使用与登录 Chrome(人员)不同的 Google 帐户。

\n

Ivo*_*vor 4

我本来可以编辑上一个问题,但我要回答它:

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))
Run Code Online (Sandbox Code Playgroud)

响应将是一个 URL:

https://<extension_id>.chromiumapp.org/oauth2?code=4/A<code>#

返回的代码可以兑换只能使用1次的令牌。https://www.googleapis.com/oauth2/v4/token然后,您将使用以下代码片段作为请求发送 POST 请求:

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
Run Code Online (Sandbox Code Playgroud)

响应将是一个 JSON 对象,您可以使用它大约 1 小时向 Google API 发出请求:

{
    "access_token": "<access_token>",
    "token_type": "Bearer",
    "expires_in": 3578
}
Run Code Online (Sandbox Code Playgroud)

最后,在访问令牌过期之前,您可以调用launchWebAuthFlow()interactive: false它将返回一个新代码,您将获得一个新令牌。