Подтвердить что ты не робот

Как заблокировать базу данных Firebase любому пользователю из определенного (электронной почты) домена?

У меня есть небольшой персональный Firebase webapp, который использует базу данных Firebase. Я хочу защитить (заблокировать) это приложение для любого пользователя из одного конкретного домена. Я хочу выполнить проверку подлинности с помощью Google. Я не понимаю, как настроить правила, чтобы сказать: "Только пользователи из одного конкретного домена (скажем @foobar.com) могут читать и записывать в эту базу данных".

(Часть проблемы, которую я вижу: трудно загружать базу данных с достаточной информацией, чтобы сделать эту работу использования. Мне нужно знать адрес электронной почты пользователя во время проверки подлинности, но auth объект не содержит электронная почта. Кажется, проблема с куриным яйцом, потому что мне нужно написать правила Firebase, которые относятся к данным в базе данных, но эти данные еще не существуют, потому что мой пользователь не может писать в базу данных.)

Если auth имел электронную почту, я мог бы легко писать правила.

Спасибо заранее!

4b9b3361

Ответ 1

Если вы используете новую Firebase, теперь это возможно, так как email доступен в правилах безопасности.

В правилах безопасности вы можете получить доступ как к адресу электронной почты, так и к проверке, что делает возможными некоторые возможные варианты использования. С этими правилами, например, только аутентифицированный, проверенный пользователь Gmail может написать свой профиль:

{
  "rules": {
    ".read": "auth != null",
    "gmailUsers": {
      "$uid": {
        ".write": "auth.token.email_verified == true && 
                   auth.token.email.matches(/.*@gmail.com$/)"
      }
    }
  }
}

Вы можете ввести эти правила в Firebase Database console вашего проекта.

Ответ 2

ПРЕДУПРЕЖДЕНИЕ: не доверяйте этому ответу. Только здесь для обсуждения.

TL;DR: Я не думаю, что это возможно, без запуска вашего собственного сервера.

Здесь моя попытка:

{
  "rules": {
    ".read": "auth.provider === 'google' && root.child('users').child(auth.uid).child('email').val().endsWith('@foobar.com')",
    ".write": "auth.provider === 'google' && root.child('users').child(auth.uid).child('email').val().endsWith('@foobar.com')",
    "users": {
      "$user_id": {
        ".write": "auth.provider === 'google' && $user_id === auth.uid && newData.child('email').val().endsWith('@foobar.com')"
      }
    }
  }
}

Я считаю, что выше сказанное говорит "только разрешить людям создавать нового пользователя, если они аутентифицированы Google, пытаются записать в базу данных node для themselve ($user_id === auth.uid), а их адрес электронной почты заканчивается на foobar.com".

Однако была отмечена проблема: любой веб-клиент может легко изменить свою электронную почту (используя консоль dev) до отправки сообщения в Firebase. Поэтому мы не можем доверять данным пользовательской записи при их хранении в Firebase.

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

Для записи я вставляю своего пользователя таким образом:

function authDataCallback(authData) {
  if (authData) {
    console.log("User " + authData.uid + " is logged in with " + authData.provider + " and has displayName " + authData.google.displayName);
    // save the user profile into the database so we can list users,
    // use them in Security and Firebase Rules, and show profiles
    ref.child("users").child(authData.uid).set({
      provider: authData.provider,
      name: getName(authData),
      email: authData.google.email
    });

Как вы могли бы себе представить, определенный пользователь мог бы перезаписать здесь значение email (например, с помощью DevTools).

Ответ 3

Вот код, отлично работающий с моей базой данных, я установил правило, что только электронные письма моей компании могут читать и записывать данные моей базы данных firebase.

{
  "rules": {
    ".read": "auth.token.email.matches(/.*@yourcompany.com$/)",


        ".write": "auth.token.email.matches(/.*@yourcompany.com$/)"
      }
    }

Ответ 4

Код, который работает для меня.

export class AuthenticationService {

    user: Observable<firebase.User>;

    constructor(public afAuth: AngularFireAuth) {
        this.user = afAuth.authState;
    }

    login(){
        var provider = new firebase.auth.GoogleAuthProvider();
        provider.setCustomParameters({'hd': '<your domain>'});
        this.afAuth.auth.signInWithPopup(provider)
        .then(response => {
            let token = response.credential.accessToken;
            //Your code. Token is now available.
        })
    }
}

Ответ 5

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

Это мой обходной путь (приложение Angular):

this.userService.login(this.email.value, this.password.value).then(data => {
  if (data.user.emailVerified === true) {
    //user is allowed
  } else {
    //user not allowed, log them out immediatly
    this.userService.logout();
  }
}).catch(error => console.log(error));