我正在构建一个 React 应用程序,其中功能的一个关键部分是用户可以登录他们的 Google 帐户,然后访问他们最近的 Google Drive/Docs 提及和通知的提要。用户到达我的网站,我与加载谷歌OAuth2用户端我client_id,apiKey,scope和discoveryDocs,他们可以点击一个按钮来登录。为了方便起见,我想用户不必重新登录并重新授权使用每次使用应用程序或应用程序刷新时,他们的 Google 帐户,我希望跨会话保存登录信息。为此,我将使用 localStorage 开始,但最终会集成一个像 Firebase 这样的数据库。
在浏览了 JavaScript 客户端 Google OAuth2 文档后,我了解了大多数事情是如何工作的 - 了解存储在 GoogleUser、GoogleAuth 等对象中的数据和方法。我在访问和刷新令牌方面遇到了一些麻烦。我知道您可以通过身份验证用户的信息gapi.auth2.getAuthInstance().currentUser.get()并gapi.auth2.getAuthInstance().currentUser.get().getAuthResponse()返回一个对象,其中包含很多我认为我需要的东西id_token,access_token以及像expires_at和 之类的元数据token_type。我还看到了grantOfflineAccess()从中提取的方法response.code,但我不太确定这些标记化字符串中的哪一个是正确使用的,以及我需要如何使用它。
Google 的这个 FAQ ( https://developers.google.com/api-client-library/javascript/help/faq ) 有点帮助但建议这样做 Refresh the token by calling gapi.auth.authorize with the client ID, the scope and immediate:true as parameters.,但是gapi.auth.authorizeGoogle 在客户端 JS OAuth2 库中指出它与更广泛地使用和大量记录api.auth2.init和signIn。
我也从像Google OAuth2 API Refresh Tokens这样的帖子中得到一个模糊的想法,我需要遵循服务器端 OAuth2 说明,我只能refresh_token通过服务器端调用来获得它,但我仍然有点茫然。我会警告并说我更像是一名前端开发人员/设计师,所以我在我的节点和服务器端技能方面摇摇欲坠。
TL; dr:我不知道如何让通过 Google OAuth2 登录的用户在刷新后保持登录状态。我有一个想法,这是因为refresh_token和access_token我访问他们,但我不知道以后该怎么办,在将数据发送到谷歌服务器,获取信息回来,并设置令牌信息为给定的用户而言,当他们返回。
这是我调用 componentDidMount 的方法(基本上是在我的应用程序首次加载时):
loadGoogleClient = () => {
gapi.load("client:auth2", () => {
gapi.auth2.init({
'client_id': my-client-id,
'apiKey': my-key,
'scope': "https://www.googleapis.com/auth/drive.readonly",
'discoveryDocs': ['https://content.googleapis.com/discovery/v1/apis/drive/v3/rest']
})
// Listen for sign-in state changes.
console.log(`User is signed in: ${gapi.auth2.getAuthInstance().isSignedIn.get()}`);
gapi.client.load("https://content.googleapis.com/discovery/v1/apis/drive/v3/rest")
.then(() => { console.log("GAPI client loaded for API");
}, (error) => { console.error("Error loading GAPI client for API", error);
});
console.log('Init should have worked');
});
}
这是我的代码,它位于我的登录按钮上:
authGoogle = () => {
gapi.auth2.getAuthInstance()
.signIn({scope: "https://www.googleapis.com/auth/drive.readonly"})
.then(function() { console.log("Sign-in successful"); },
function(err) { console.error("Error signing in", err); });
}