Firestore проверить, если вошедший в систему пользователь подтвердил свою электронную почту - PullRequest
0 голосов
/ 02 апреля 2020

Итак, у меня есть коллекция в firestore, которая должна быть доступна только зарегистрированным и проверенным пользователям.

Вот как я ее защищаю:

rules_version = '2';

service cloud.firestore {
  match /databases/{database}/documents {
    function userIsAdmin() {
      return request.auth.token.accessLevel >= 200;
    }
    function emailVerified() {
      return request.auth.token.firebase.sign_in_provider != 'password'
            || request.auth.token.email_verified == true;
    }
    function isAuthed() {
      return request.auth.uid != null && emailVerified(); // If I remove the && emailVerified() part, it works again in the frontend
    }
    function userIsSameAsResource(userId) {
      return request.auth.uid == userId && emailVerified();
    }

    match /users/{userId} {

      allow get: if isAuthed();
      allow list: if userIsAdmin();

      allow create, delete: if userIsAdmin();
      allow update: if userIsAdmin()
                      || userIsSameAsResource(userId);
    }
  }
}

С помощью эмулятора правил это работает как и ожидалось:

  • поставщик Google Auth, электронная почта не подтверждена: чтение разрешено
  • поставщик Google Auth, электронная почта подтверждена: чтение разрешено (но на самом деле не требуется, поскольку мы не отправляем проверки для поставщиков кроме электронной почты)
  • поставщик аутентификации электронной почты, адрес электронной почты не подтвержден: чтение не разрешено
  • поставщик аутентификации электронной почты, адрес электронной почты подтвержден: чтение разрешено

Но с использованием внешнего интерфейса это происходит:

  • поставщик Google Auth, электронная почта не подтверждена: чтение разрешено
  • поставщик Google Auth, электронная почта подтверждена: чтение разрешено
  • Email Auth провайдер, электронная почта не подтверждена: чтение не разрешено
  • Email Auth провайдер, электронная почта подтверждено: чтение не разрешено → не удается с Missing or insufficient permissions

Вот соответствующий фрагмент домашние животные из моего внешнего кода:

// currentAuthUserObs() is the current auth user from firebase  (that part works)
// isEmailVerified() is described further down (works too)
// afStorage is AngularFire2's Firestore module

// 'HERE' and 'HERE2' are both printed, so that works as expected. The problem really is the query

this.auth.currentAuthUserObs().subscribe(async (authUser) => {
    console.log('HERE');
    if (authUser != null && await this.auth.emailAuth.isEmailVerified()) {
        console.log('HERE2');
        this.afStorage.doc(`${FirestoreCollections.USERS}/${authUser.uid}`).valueChanges()
            .subscribe(user => {
                console.log(user);
            });
    }
});


// In my case isEmailVerified gets called before and refreshes the currentUser, so it is ok to not call it with `refresh = true` in the subscription above.
public async isEmailVerified(refresh = false): Promise<boolean> {
    if (refresh) {
        await firebase.auth().currentUser.reload();
    }

    const isEmail = () => firebase.auth().currentUser.providerData.some(provider => provider.providerId == 'password');
    return isEmail() ? firebase.auth().currentUser.emailVerified : true;
}

Кто-нибудь знает, в чем проблема?

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