如何让Google身份验证与ReactJs一起使用?

时间:2017-04-25 17:56:06

标签: reactjs authentication google-authentication

我一直在尝试使用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很新,但希望这是可以理解的!

很抱歉这篇长篇文章,非常感谢您的时间,如果您有任何疑问,请直接询问!

2 个答案:

答案 0 :(得分:2)

可以使用React google登录组件。它的工作对我来说。

react google login

答案 1 :(得分:1)

我得到了它的工作,除了一些来自gapi的小问题: “无法读取null的属性'样式',这显然与gapi没有找到登录按钮或类似的东西有关。我发现没有任何功能错误。

为了将来参考,这就是我所做的(有点像一个quickfix但至少它现在正在工作):

现在所有路线都有一个封闭所有路线的路线容器。这样,在访问任何路由之前总是调用容器,我可以在那里处理所有身份验证和登录。

在这个容器(称为Base)中是一个事件监听器,用于监听gapi(谷歌平台脚本)何时完成加载。当事件触发时我存储了gapi,并且在auth2中将auth2作为状态变量标记存储在Base中。它们只加载一次,从那时起它们将通过道具传递给所有需要它们的组件。

我的Header.js现在有登录和退出按钮。一个是隐藏的,而另一个是根据你是否登录显示。

每次重新渲染都会调用

onSignIn(googleUser),因为您重新渲染了Google登录按钮。由于这意味着“用户点击并登录,所以让我们重定向”式,这意味着Header.js必须记住登录状态。 (它是重新渲染还是用户实际登录?)onSignIn会因为'onsuccess'数据标记而在每次渲染时调用。

由于事件是异步的,因此在使用gapi和auth2更新状态时强制重新渲染。

希望这可以帮助一些人!