我正在构建一个React应用程序,其中功能的关键部分是用户可以登录其Google帐户,然后访问其最新Google云端硬盘/文档提及和通知的Feed。用户到达我的网站,我用我的client_id
,apiKey
,scope
和discoveryDocs
加载Google OAuth2客户端,他们可以点击按钮登录。为方便起见,我希望用户不必重新登录每次他们使用应用程序或应用程序刷新时,使用他们的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(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.
,但是Google在客户端JS OAuth2库中注意到gapi.auth.authorize
与更广泛使用且记录较多的api.auth2.init
和signIn
不兼容。
我在Google OAuth2 API Refresh Tokens这样的帖子中也有一个模糊的想法,我需要遵循服务器端OAuth2指令,我只能通过服务器端调用得到这个refresh_token
,但我仍然有点亏。我会告诫说我不仅仅是一名前端开发人员/设计师,所以我对我的节点和服务器端技能感到不稳定。
TL;博士:我不知道如何保持通过Google OAuth2登录的用户在刷新后登录。我有一个想法,这是由于refresh_token
和access_token
,我可以访问它们但我不知道该怎么做,在向Google服务器发送数据,获取信息,以及为给定用户设置令牌信息方面当他们回来。
这是调用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); });
}
如果你使用的是客户端lib(gapi api),则不需要刷新令牌......一旦登录,它应该会持续跨会话并刷新...问题是代码......
1)将其包含在index.html
部分的head
中:
<script src="https://apis.google.com/js/api.js"></script>
2)这是一个组件,它将使用gapi
lib处理auth并有条件地渲染一个按钮(代码是不言自明的,但如果你有一个问题只是问...)
import React from 'react';
class GoogleAuth extends React.Component {
state = { isSignedIn: null };
componentDidMount() {
window.gapi.load('client:auth2', () => {
window.gapi.client
.init({
clientId: '<your client id here...>',
scope: 'email', // and whatever else passed as a string...
})
.then(() => {
this.auth = window.gapi.auth2.getAuthInstance();
this.handleAuthChange();
this.auth.isSignedIn.listen(this.handleAuthChange);
});
});
}
handleAuthChange = () => {
this.setState({ isSignedIn: this.auth.isSignedIn.get() });
};
handleSignIn = () => {
this.auth.signIn();
};
handleSignOut = () => {
this.auth.signOut();
};
renderAuthButton() {
if (this.state.isSignedIn === null) {
return null;
} else if (this.state.isSignedIn) {
return <button onClick={this.handleSignOut}>Sign Out</button>;
} else {
return <button onClick={this.handleSignIn}>Sign in with Google</button>;
}
}
render() {
return <div>{this.renderAuthButton()}</div>;
}
}
export default GoogleAuth;
现在您只需在应用程序的任何位置使用此组件/按钮...如果您有导航组件,只需将其导入并将其用作按钮登录/注销...