开发者问题收集

如何让 Google 身份验证与 ReactJs 配合使用?

2017-04-25
19853

我整天都在尝试让 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);
  }

主页只是一个登录页面,由登录组件处理,如果身份验证成功,它会将用户重定向到 /auth。每次访问受保护的路由时,AuthUserContainer 都会持续处理身份验证。

登录组件有 Google 登录按钮,所有受保护的路由(通过布局组件)都有 Google 退出按钮。

我的 Header.js 包含“Google 退出按钮”(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>
    );
  }
}

我使用了 Google 自己的示例代码,并尝试针对 React 对其进行调整。我使用此代码时遇到的问题是“未捕获 TypeError:无法读取未定义的属性‘getAuthInstance’”。由于我将登录和退出按钮拆分到单独的页面,因此 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>
    );
  }
}

我也基于 Google 自己的代码编写了此代码,但根本不起作用(按钮未加载,只是什么都没有显示,或者它从未调用 onSignIn)。我还找到并尝试了 这个 ,它让它有点工作(有时)。我还尝试在 renderGoogleLoginButton() 中初始化 auth2,但这也只在某些时候有效...

renderGoogleLoginButton() 由自定义事件(google-loaded)的事件处理程序调用,该事件在 Google API 加载时触发(与链接中完全一样)。 Authenticate 是我自己的类,它将我创建的 token、getUserName 函数等捆绑在一起。

我还从 gapi 收到以下错误:“未捕获的 TypeError:无法读取 null 的属性‘style’”,我认为它试图引用登录/退出按钮,但由于它们在当时未加载,因此它们为空。

我找不到任何不会导致故障或错误的好解决方案。 Google 自己的代码 将所有内容放在同一个 HTML 文档中,但由于我想将其拆分为组件,因此一切都会中断。我这样做是不是完全错了?我对 React 很陌生,但希望这是可以理解的!

很抱歉发了这么长的帖子,非常感谢您抽出时间,如果您有任何问题,请随时提问!

2个回答

除了GAPI的一些小投诉外,我有效: “无法读取属性的'null''属性'”,这显然与GAPI没有找到按钮或类似的标志有关。我检测到没有功能错误。

用于将来的参考,这是我所做的(QuickFix,但至少它现在正在工作):

现在所有路线都有一个路由容器包装所有路线。这样,在访问任何路线之前,总是调用容器,我可以在此操作所有身份验证和登录。

在此容器中(称为base)是一个事件列表,是gapi(Google Platform脚本)完成加载。当事件发射时,我将GAPI存储,INITS和INITS AUTH2作为基本的状态差异。它们只有一次加载,从那时起,它们将被传递给所有需要它们的组件。

我的标题。一个是隐藏的,另一个是根据您是否登录的。由于这是“用户单击并登录的用户,因此让我们重定向” - 式的这意味着header.js必须记住登录状态。 (它是重新渲染还是用户实际登录?)onsignin被称为每一个渲染,因为“ OnSuccess”数据标签。

,因为事件是异步的,当时是在状态时强制重新渲染的已使用GAPI和AUTH2进行更新。

希望这对某些人有帮助!

Empha
2017-04-26

React google login 组件可用。它对我有用。

react google login

Jose G Varanam
2017-06-05