Сохранение входа пользователя в систему после обновления / использования токена обновления с помощью Google OAuth2 в приложении React - PullRequest
2 голосов
/ 21 марта 2019

Я создаю приложение React, в котором ключевой частью функциональности является то, что пользователь может войти в свою учетную запись Google, а затем получить доступ к каналу своих последних упоминаний и уведомлений в Google Диске / Документах.Пользователь заходит на мой сайт, где я загружаю клиент Google OAuth2 с моими client_id, apiKey, scope и discoveryDocs, и они могут нажать кнопку для входа. Для удобства я бы хотел, чтобы пользовательчтобы не приходилось повторно входить в систему и повторно авторизовываться с помощью своей учетной записи Google каждый раз, когда они используют приложение или обновляет приложение, я хотел бы, чтобы информация для входа сохранялась между сеансами.Для этого я буду использовать localStorage для начала, но в конечном итоге интегрирую базу данных, такую ​​как Firebase.

Просматривая клиентскую документацию Google OAuth2 клиента JavaScript, я понимаю, как работает большинство вещей, - понимаю данные и методы, хранящиеся в объектах GoogleUser, GoogleAuth и т. Д.У меня небольшие проблемы с доступом и обновлением токенов.Я понимаю, что вы можете получить информацию аутентифицированного пользователя через gapi.auth2.getAuthInstance().currentUser.get() и gapi.auth2.getAuthInstance().currentUser.get().getAuthResponse() возвращает объект с большим количеством того, что мне нужно, например id_token, access_token и метаданные типа expires_at и token_type.Я также вижу метод grantOfflineAccess(), из которого я извлекаю response.code, но я не совсем уверен, какая из этих токенизированных строк является правильной и как мне нужно ее использовать.

Этот FAQ от 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., но в клиентской библиотеке JS OAuth2 Google отмечает gapi.auth.authorize как несовместимую с более широко используемым иapi.auth2.init и signIn.

У меня также есть смутная идея из сообщений, таких как Google OAuth2 API Refresh Token , что мне нужно следовать инструкциям OAuth2 на стороне сервера, и я могу толькополучить это refresh_token через вызов на стороне сервера, но я все еще в некоторой растерянности. Я предостерегаю и говорю, что я скорее разработчик / дизайнер внешнего интерфейса, так что я неуверен в своем узле инавыки работы на стороне сервера.

TL; dr: я не знаю, как сохранить учетную запись моих пользователей, вошедших через Google OAuth2, после обновления. У меня есть идея, что это из-за refresh_tokenи access_token и у меня есть к ним доступ, но я не знаю, что делать после этого, с точки зрения отправки данных на серверы Google, получения информации и установки информации о токене для данного пользователя при его возвращении.

Вот мой яthod, который вызывает 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); });
}

1 Ответ

0 голосов
/ 21 марта 2019

Если вы используете клиентскую библиотеку lib (api gapi), то нет необходимости в обновлении токена ... После входа в систему он должен сохраняться между сеансами и обновляться ... Проблема заключается в коде ...

1) Включите это в index.html в разделе head:

<script src="https://apis.google.com/js/api.js"></script>

2) Вот компонент, который будет обрабатывать аутентификацию с использованием библиотеки gapi и отображать кнопку условно (Код не требует пояснений, но если у вас есть вопрос, просто спросите ...)

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;

Теперь вы можете просто использовать этот компонент / кнопку в любом месте вашего приложения ... То есть, если у вас есть компонент навигациипросто импортируйте его туда и используйте как кнопку входа / выхода ...

...