Учетная запись службы Firebase для создания токена аутентификации для использования на стороне клиента с помощью скрипта Google Apps - PullRequest
0 голосов
/ 09 февраля 2019

Мне трудно использовать FirebaseApp (сторонний API) для создания токена аутентификации, который может быть передан на боковую панель и использован клиентом для входа и доступа к моей клиентской стороне базы данных Firebase.

Я пытаюсь использовать этот учебник , но не могу заставить его работать без использования секрета базы данных (который не рекомендуется) в makeToken().Я бы предпочел использовать служебную учетную запись, как указано в этого руководства .Когда я смотрю на разницу между сгенерированными токенами, первые две части разделяются символом '.'идентичны, последний кусок после финального '.'это отличается.Длина одинакова.Например:

//Example Generated by Database Secret: TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBv.ZGdlLCBleGNlZWRzIHRoZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4=.dGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2U= 
//Example Generated by Service Account: TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBv.ZGdlLCBleGNlZWRzIHRoZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4=.IHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbml=

Я могу сгенерировать токен доступа OAuth, передать его в FirebaseApp и сгенерировать токен аутентификации, но когда он передается на стороне клиента и я пытаюсь аутентифицироваться, я получаю ошибку: Login Failed! Error: INVALID_TOKEN: Failed to validate MAC.

Кажется, что есть много дезинформации и противоречивой информации о том, как это должно быть сделано.


У меня есть getFirebaseService() функция на стороне серверакоторый использует библиотеку OAuth2 скрипта Apps для получения токена доступа.

function getFirebaseService() {  
  return OAuth2.createService('Firebase')
      // Set the endpoint URL.
      .setTokenUrl('https://accounts.google.com/o/oauth2/token')

      // Set the private key and issuer.
      .setPrivateKey(fb_PRIVATE_KEY) //Service account private key
      .setIssuer(fb_SERVICE_EMAIL) //Service account email

      // Set the property store where authorized tokens should be persisted.
      .setPropertyStore(PropertiesService.getScriptProperties())

      // Set the scopes.
      .setScope('https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/firebase.database');
}

У меня есть функция makeToken() на стороне сервера, которая получает токен аутентификации от Firebase с помощью токена доступа OAuth.Я могу использовать серверный токен OAuth service.getAccessToken() для доступа и хранения данных.Так что это работает, я думаю, моя проблема заключается в создании клиентского токена авторизации, который является более ограничительным.

function makeToken(){ 
  var service = getFirebaseService();
  if (service.hasAccess()) {
    return FirebaseApp.getDatabaseByUrl(fb_URL, service.getAccessToken()) //Database Secret Works: "AAslhfi3MYACCESSTOKEN2930hf03ah4th8" but is being depreciated.
                    .createAuthToken(Session.getActiveUser().getEmail());
  } else {
    Logger.log("makeToken: " + service.getLastError());
  }
}

Затем на стороне клиента, с боковой панели, я пытаюсь аутентифицироваться с помощью пользовательского токена аутентификации, полученного со стороны сервера изmakeToken().

var userAuthToken;

google.script.run.withSuccessHandler(function (requestAuthToken) {
  userAuthToken = authenticateClient(requestAuthToken)
}).makeToken();

function authenticateClient(userRequestToken) {
  var ref = new Firebase(fb_URL);

  ref.authWithCustomToken(userRequestToken, function (error, authData) {
    if (error) {
      console.log("FB Login Failed!", error); //Error below come from here.
    }
    else {
      console.log("FB Login Succeeded!", authData);      
    }
  });

  return ref.authData.auth; 
}

Это приводит к Login Failed! Error: INVALID_TOKEN: Failed to validate MAC..

Редактировать: Возможно ли, что FirebaseApp неправильно генерирует аутентификацию JWTТокен?

Edit2: Я думаю, что вышеописанное редактирование маловероятно, так как я пытался использовать библиотеку GSApp и имел ту же проблему.Кажется, он хочет получить только секретную базу данных, а не служебную учетную запись OAuth.

1 Ответ

0 голосов
/ 10 февраля 2019

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

OAuth2 (на стороне сервера) Ссылка

Мне не пришлось ничего менять здесь!Это работало нормально и никогда не было проблемой.


FirebaseApp (на стороне сервера) Ссылка

Это хорошая библиотека, и язастрял с ним, потому что он работал хорошо (как только я получил его там).Мне пришлось внести изменения в мой исходный код, который был взят из учебника , о котором я упоминал.Мой код закончился следующим образом и работал:

if (service.hasAccess()) {   
    return FirebaseApp.getDatabaseByUrl(fb_URL, service.getAccessToken()) //get OAuth Token
                      .createAuthToken(Session.getEffectiveUser().getEmail(), null, serviceAccount.client_email, serviceAccount.private_key);
  //... Added the null, private key, and service email parameters.

Firebase (на стороне клиента) Ссылка

Хорошо, так что , где моя основная проблема была - Учебное пособие , которое я использовал для настройки на стороне клиента, было старое .Мне пришлось обновить код самостоятельно, чтобы использовать новую версию 3.x:

<script src="https://www.gstatic.com/firebasejs/5.8.2/firebase.js"></script>

// Initialize Firebase
var config = {
  apiKey: "<Web API Key>",
  authDomain: "<Project ID>.firebaseapp.com",
  databaseURL: "https://<DB URL>.firebaseio.com/"
  };

firebase.initializeApp(config);

С помощью этого экземпляра firebase я смог обновить свой оригинальный метод authenticateClient():

function authenticateClient(userRequestToken) {
  firebase.auth().signInWithCustomToken(userRequestToken).catch(function(error) {
    // Handle Errors here.
    console.error("authClient: ", error.code, error.message);
  });

  return {
    uid: firebase.auth().currentUser.uid,
    metadata: {
      lastSignInTime: firebase.auth().currentUser.lastSignInTime
    }
  }; 
}

Вот и все!Теперь у меня есть экземпляр firebase с зарегистрированным пользователем через JWT Custom Token!Я столкнулся с несколькими людьми с похожими проблемами, и я надеюсь, что это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...