使用谷歌登录按钮与反应

时间:2015-07-24 12:22:31

标签: javascript reactjs google-signin

我正在尝试在反应应用程序中使用谷歌登录。 虽然在应用程序外部使用登录按钮本身很有效,但在自定义SignIn组件中使用它时,我无法按预期工作。 当用户登录时,按钮本身应该执行data-onsuccess方法。 问题是,即使登录有效,执行也永远不会达到该方法。

我可能错过了一些反应但我无法找到它。有帮助吗?在下面找到加载所有内容和组件本身的html。

<head>
    <meta name="google-signin-scope" content="profile email">
    <meta name="google-signin-client_id" content="1234-real-client-id.apps.googleusercontent.com">
    <script src="https://apis.google.com/js/platform.js" async defer></script>
</head>
<body>
    <!-- Here is where everything gets displayed -->
    <div id="app"></div>

    <!-- The file with the js code -->
    <script src="/js/main.js"></script>
</body>


var SignIn = React.createClass({
    onSignIn : function (google_user) {
        // I want this method to be executed
    },

    render : function() {
        return (
            <div className="g-signin2" data-onsuccess={this.onSignIn} data-theme="dark" />
        );
    }
});

请注意,我没有在此处粘贴不相关的代码;)

6 个答案:

答案 0 :(得分:27)

componentDidMount()初始化组件时尝试添加onSuccess回调。

componentDidMount: function() {
  gapi.signin2.render('g-signin2', {
    'scope': 'https://www.googleapis.com/auth/plus.login',
    'width': 200,
    'height': 50,
    'longtitle': true,
    'theme': 'dark',
    'onsuccess': this. onSignIn
  });  
},
...

来源:https://developers.google.com/identity/sign-in/web/build-buttonhttps://github.com/meta-meta/webapp-template/blob/6d3e9c86f5c274656ef799263c84a228bfbe1725/app/Application/signIn.jsx

答案 1 :(得分:1)

我需要在功能组件中使用它,以为我会分享如何修改它,我需要使用useEffectHook,它可以用来代替componentDidMount

  useEffect(() => {
    window.gapi.signin2.render('g-signin2', {
      'scope': 'https://www.googleapis.com/auth/plus.login',
      'width': 200,
      'height': 50,
      'longtitle': true,
      'theme': 'dark',
      'onsuccess': onSignIn
    })
  })

答案 2 :(得分:1)

现在,您可以使用此React Google Login NPM软件包来封装所有设置工作。您只能将选项传递给组件。

import React from 'react';
import ReactDOM from 'react-dom';
import GoogleLogin from 'react-google-login';
// or
import { GoogleLogin } from 'react-google-login';
 
 
const responseGoogle = (response) => {
  console.log(response);
}
 
ReactDOM.render(
  <GoogleLogin
    clientId="658977310896-knrl3gka66fldh83dao2rhgbblmd4un9.apps.googleusercontent.com"
    buttonText="Login"
    onSuccess={responseGoogle}
    onFailure={responseGoogle}
    cookiePolicy={'single_host_origin'}
  />,
  document.getElementById('googleButton')
);

该代码来自软件包的文档。

答案 3 :(得分:0)

只需确保将Google的platform.js脚本标签添加到React应用的index.html

<script src="https://apis.google.com/js/platform.js" async defer></script>

从以下位置获取您的客户ID:

https://console.developers.google.com/apis/credentials


这是Typescript中的示例实现,因此您可以作为启发:

const Login = () => {
  // const {
  //   state,
  //   dispatch,
  // } = initContext();

  const onSignIn = (googleUser) => {
    const token = googleUser.getAuthResponse().id_token;
    console.log(token);

    // dispatch({
    //   type: 'login',
    // });
  };

  const onFail = ({error}) => {
    console.log(error);
  };

  useEffect(() => {
    // @ts-expect-error
    const { gapi } = window;

    gapi.load('auth2', () => {
      const auth2 = gapi.auth2.init({
        client_id: '...',
      });

      gapi.signin2.render('signin-button', {
        width: 232,
        height: 40,
        longtitle: true,
        onsuccess: onSignIn,
        onfailure: onFail,
      });
    });
  }, []);

  return (
    <div id="signin-button"></div>
  );
};

答案 4 :(得分:0)

没有其他答案对我有用。最终有效的方法是使用id而不是class作为div上的标识符。

<div id="g-signin2" />

代替

<div className="g-signin2" />

除了使用window.gapi.signin2.render作为其他答案以外。

答案 5 :(得分:0)

可能有点晚了,但我想分享我的实施过程。 就我而言,我想完全自定义按钮,并且还想拥有某种加载程序。我使用钩子重新实现了这个

/* istanbul ignore file */
import { useState, useEffect, useCallback } from 'react';
import { APP_IDS } from 'utils/constants';

const initgAuth = () =>
  // eslint-disable-next-line no-unused-vars
  new Promise((resolve, _reject) => {
    // eslint-disable-next-line no-undef
    gapi.load('auth2', () => {
      // eslint-disable-next-line no-undef
      const auth = gapi.auth2.init({
        client_id: APP_IDS.Google,
      });
      resolve(auth);
    });
  });

const initializeGoogle = () =>
  // eslint-disable-next-line no-unused-vars
  new Promise((resolve, _reject) => {
    if (typeof gapi !== 'undefined') {
      window.googleAsyncInit().then(auth => {
        resolve(auth);
      });
    } else {
      // eslint-disable-next-line func-names
      window.googleAsyncInit = async function() {
        const auth = await initgAuth();
        resolve(auth);
        return auth;
      };

      // eslint-disable-next-line func-names
      (function(d, s, id) {
        let js;
        const gjs = d.getElementsByTagName(s)[0];
        if (d.getElementById(id)) {
          return;
        }
        // eslint-disable-next-line prefer-const
        js = d.createElement(s);
        js.id = id;
        js.src = 'https://apis.google.com/js/platform.js';
        js.onload = window.googleAsyncInit;
        gjs.parentNode.insertBefore(js, gjs);
      })(document, 'script', 'google_api');
    }
  });

const useGoogle = () => {
  const [google, setGoogle] = useState([]);
  const [isReady, setReady] = useState(false);

  const initGoogle = useCallback(async () => {
    const auth = await initializeGoogle();
    if (auth !== 'undefined') {
      setGoogle(auth);
      setReady(true);
    }
  });

  useEffect(() => {
    initGoogle();
  }, [initGoogle]);

  return [google, isReady];
};

所以我可以在任何像这样的组件中使用它

  const [GoogleInstance, isGoogleReady] = useGoogle();

   GoogleInstance.signIn().then(response => {
      const authResponse = response.getAuthResponse(true);
      doGoogleLogin(authResponse);
    });

这非常方便,因为我能够确保在用户与按钮本身交互之前加载了 SDK。如果您有不同的组件/页面需要 google 登录,也可以使用