我一直在尝试使用Google身份验证与React一起工作,但在搜索了几个小时之后我尝试了一切,我只得到一辆马车,有时候工作,一团糟。谁能看到我做错了什么? (这是针对学校项目所以我正在学习!)
该项目将成为在线时间表创建者。
我的主要Index.js具有以下渲染功能:
function renderApp() {
ReactDOM.render(
<Router history={browserHistory}>
<Route path="/" component={Login}></Route>
<Route component={AuthUserContainer}>
<Route path="/auth" component={Layout}>
<IndexRoute component={Overview}></IndexRoute>
<Route path="schedule(/:scheduleid)" component={Schedule}></Route>
</Route>
</Route>
</Router>,
app);
}
主页只是一个登录页面,由Login组件处理,如果认证成功,它将把用户重定向到/ auth。每次访问受保护的路由时,AuthUserContainer都会持续进行身份验证。
“登录”组件具有“Google登录”按钮,所有受保护的路线都有(通过布局组件)Google退出按钮。
我的Header.js包含&#34; Google退出按钮&#34; (signOutHandler):
export default class Header extends React.Component {
constructor(props) {
super(props);
this.state = {};
this.SignOutHandler = this.SignOutHandler.bind(this);
}
SignOutHandler() {
var auth2 = gapi.auth2.getAuthInstance();
auth2.signOut().then(function () {
console.log('User signed out.');
Authenticate.signOutUser();
});
}
render() {
return (
<div class="header-content">
<h2 class="header-title">Schedule</h2>
<h3 class="header-user-button">
<a href="/" onClick={this.SignOutHandler}>User First Name</a>
</h3>
</div>
);
}
}
我使用Googles自己的示例代码并试图为React调整它。我用这段代码得到的问题是&#34; Uncaught TypeError:无法读取属性&#39; getAuthInstance&#39;未定义&#34;。由于我将登录和注销按钮拆分为单独的页面,因此auth2无法正确初始化,但单击该按钮两次可以使其正常工作。试图在这里手动初始化它通常会给我一个Gapi未定义的错误......
最后是Login.js:
export default class Login extends React.Component {
constructor(props) {
super(props);
this.state = {};
this.onSignIn = this.onSignIn.bind(this);
this.renderGoogleLoginButton = this.renderGoogleLoginButton.bind(this);
}
renderGoogleLoginButton() {
console.log('rendering google signin button')
gapi.signin2.render('my-signin2', {
'scope': 'https://www.googleapis.com/auth/plus.login',
'width': 200,
'height': 50,
'longtitle': true,
'theme': 'light',
'onsuccess': this.onSignIn
});
gapi.load('auth2', function() {
gapi.auth2.init();
});
}
componentDidMount() {
window.addEventListener('google-loaded', this.renderGoogleLoginButton);
}
onSignIn(googleUser) {
Authenticate.signInUser(googleUser.getBasicProfile());
this.props.router.push("/auth");
}
render() {
return (
<div class="container">
<h2 class="form-signin-heading">
Sign-in with Google account required
</h2>
<div id="my-signin2"></div>
</div>
);
}
}
我也将此代码基于Googles自己的代码,但这根本不起作用(按钮没有加载,根本没有显示,或者它从未调用onSignIn)。我也找到并尝试了this,这使它有点工作(有时候)。我还尝试在renderGoogleLoginButton()中初始化auth2,但这只会在以后工作...
renderGoogleLoginButton()由自定义事件(google-loaded)的even-handler调用,该事件在加载Google API时触发(与链接中的完全相同)。 Authenticate是我自己的类,它将我的token,getUserName函数等创建捆绑在一起。
我也从gapi得到以下错误:&#34; Uncaught TypeError:无法读取属性&#39; style&#39; of null&#34;,我认为它试图引用登录/注销按钮,但因为它们在它们为空时没有被加载。
我找不到任何不会导致故障或错误的好解决方案。 Googles own code将所有内容放在同一个HTML文档中,但由于我想将其拆分为组件,所以它都会中断。我这样做完全错了吗?我对React很新,但希望这是可以理解的!
很抱歉这篇长篇文章,非常感谢您的时间,如果您有任何疑问,请直接询问!
答案 0 :(得分:2)
可以使用React google登录组件。它的工作对我来说。
答案 1 :(得分:1)
我得到了它的工作,除了一些来自gapi的小问题: “无法读取null的属性'样式',这显然与gapi没有找到登录按钮或类似的东西有关。我发现没有任何功能错误。
为了将来参考,这就是我所做的(有点像一个quickfix但至少它现在正在工作):
现在所有路线都有一个封闭所有路线的路线容器。这样,在访问任何路由之前总是调用容器,我可以在那里处理所有身份验证和登录。
在这个容器(称为Base)中是一个事件监听器,用于监听gapi(谷歌平台脚本)何时完成加载。当事件触发时我存储了gapi,并且在auth2中将auth2作为状态变量标记存储在Base中。它们只加载一次,从那时起它们将通过道具传递给所有需要它们的组件。
我的Header.js现在有登录和退出按钮。一个是隐藏的,而另一个是根据你是否登录显示。
每次重新渲染都会调用onSignIn(googleUser),因为您重新渲染了Google登录按钮。由于这意味着“用户点击并登录,所以让我们重定向”式,这意味着Header.js必须记住登录状态。 (它是重新渲染还是用户实际登录?)onSignIn会因为'onsuccess'数据标记而在每次渲染时调用。
由于事件是异步的,因此在使用gapi和auth2更新状态时强制重新渲染。
希望这可以帮助一些人!