Использование Firebase Auth для доступа к API Календаря Google

Я создаю веб-приложение с использованием AngularJS, Firebase (SDK v3) и API Календаря Google. Я аутентифицирую пользователей с помощью Google OAuth. Моя цель - иметь возможность создавать события календаря из узлов базы данных в Firebase. До сих пор мне удалось запросить доступ к области календаря с помощью:

_authProvider = new firebase.auth.GoogleAuthProvider();
// Get permission to manage Calendar
_authProvider.addScope("https://www.googleapis.com/auth/calendar");
_fbAuthObject.signInWithRedirect(_authProvider);

Я аутентифицируюсь с потоком перенаправления, поэтому перенаправление аутентификации доступно как:

_fbAuthObject.getRedirectResult()
    .then(function _readToken(result) {
      if (result.credential) {
        _googleToken = result.credential.accessToken;
        var authHeader = 'Bearer '+ _googleToken;

        // Just a test call to the api, returns 200 OK 
        $http({
          method: 'GET',
          headers: {
            'Authorization': authHeader
          },
          url: 'https://www.googleapis.com/calendar/v3/users/me/calendarList/primary'
        })
          .then(function success(response) {
            console.log('Cal response', response);
          },
          function error(response) {
            console.log('Error', response);
          });

Однако, похоже, что за пределами первоначального входа в систему невозможно получить токен доступа Google через Firebase SDK. Кажется, возможно получить доступ только к токену Firebase JWT, но не использовать Calendar API. Я мог бы сохранить токен доступа, но это не решило бы проблемы при обновлении токена и т. Д. Есть ли способ получить текущий токен Google Access с помощью Firebase SDK и, если нет, какие другие решения существуют для этой проблемы, не имея аутентифицировать пользователя дважды?

ОБНОВЛЕНИЕ 1:

Похоже, кто-то еще боролся с подобными проблемами с аутентификацией Facebook. По этому вопросу была ссылка на документацию Firebase, в которой говорилось, что Аутентификация Firebase больше не сохраняет токен доступа. Так как я могу справиться с обновлениями токенов? Неужели нет ответа на этот вопрос?

ОБНОВЛЕНИЕ 2:

Итак, я связался со службой поддержки Firebase с запросом функции по этой проблеме, и они дали мне следующий ответ:

Спасибо, что нашли время написать нам.

Я понял вашу точку зрения, это действительно хорошее предложение. Мы точно знаем, что многим пользователям, таким как вы, нужна функция OAuth, которая будет получать доступ к токену при обновлении. Мы изучаем потенциальные решения, но я не могу гарантировать, что это будет доступно в ближайшее время. Мы будем учитывать ваши отзывы в будущем. Постоянное улучшение очень важно для нашего сообщества, поэтому спасибо за то, что подняли этот вопрос!

Следите за нашими примечаниями к выпуску для любых дальнейших обновлений.

Так что похоже, что токены доступа не доступны через Firebase SDK в данный момент. Я все еще пытаюсь найти обходной путь, поэтому, если у кого-то есть идеи по поводу правильного решения, я буду рад их услышать. И, конечно, я буду публиковать его здесь, если найду работающее решение самостоятельно.

1 ответ

Решение

Наконец-то я обошел эту проблему, обработав аутентификацию вне Firebase с помощью JavaScript-клиента Google API. Это решение требует включения клиента авторизации Google, как описано здесь. Обработка потока входа в Firebase вручную описана здесь.

gapi.auth2.getAuthInstance().signIn()
    .then(function _firebaseSignIn(googleUser) {
      var unsubscribe = firebase.auth().onAuthStateChanged(function(firebaseUser) {
        unsubscribe();
        // Check if we are already signed-in Firebase with the correct user.
        if (!_isUserEqual(googleUser, firebaseUser)) {
          // Build Firebase credential with the Google ID token.
          var credential = firebase.auth.GoogleAuthProvider.credential(
            googleUser.getAuthResponse().id_token);

          // Sign in with credential from the Google user.
          return firebase.auth().signInWithCredential(credential)
            .then(function(result) {
              // other stuff...
            });

Функция _isUserEqual:

function _isUserEqual(googleUser, firebaseUser) {
  if (firebaseUser) {
    var providerData = firebaseUser.providerData;
    for (var i = 0; i < providerData.length; i++) {
      if (providerData[i].providerId === firebase.auth.GoogleAuthProvider.PROVIDER_ID &&
        providerData[i].uid === googleUser.getBasicProfile().getId()) {
        // We don't need to reauth the Firebase connection.
        return true;
      }
    }
  }
  return false;
}

Теперь я могу ссылаться на токен доступа следующим образом:

var user = gapi.auth2.getAuthInstance().currentUser.get();
return user.getAuthResponse().access_token;

Это все еще не идеальное решение для меня, но пока оно работает, и я могу проходить аутентификацию как в Firebase, так и в Calendar API.

Другие вопросы по тегам