如何将Firebase数据库锁定到特定(电子邮件)域中的任何用户?

时间:2016-04-29 16:29:39

标签: firebase firebase-security firebase-realtime-database firebase-authentication

我有一个使用Firebase数据库的小型个人Firebase网络应用程序。我想从单个特定域向任何用户保护(锁定)此应用程序。我想通过Google进行身份验证。我不清楚如何配置规则来说“只有来自单个特定域(例如@foobar.com)的用户才能读取和写入此数据库”。

(我看到的部分问题:使用足够的信息来引导数据库很难使这个用例工作。我需要在验证时知道用户的电子邮件,但是auth object doesn'包含电子邮件。这似乎是鸡蛋问题,因为我需要编写引用数据库中数据的Firebase规则,但由于我的用户无法写入数据库,因此该数据尚不存在。)< / p>

如果auth有电子邮件,那么我可以轻松编写规则。

提前致谢!

6 个答案:

答案 0 :(得分:38)

如果您正在使用新的Firebase,现在可以使用,因为安全规则中提供了email

在安全规则中,您可以访问电子邮件地址以及是否已经过验证,从而可以实现一些很好的用例。例如,使用这些规则,只有经过身份验证的经过验证的gmail用户才能编写其个人资料:

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

您可以在项目的Firebase Database console中输入这些规则。

答案 1 :(得分:2)

警告:不要相信这个答案。就在这里讨论。

tldr:如果不运行自己的服务器,我认为这是不可能的。

这是我到目前为止的尝试:

<textarea id="something"></textarea>
<script>
$("#something").keydown(function(e){
if (e.keyCode == 13 && !e.shiftKey)
{
  e.preventDefault();
  return false;
  }
});
</script>

我相信以上所说&#34;只允许人们创建一个新用户,如果他们通过Google验证,正在尝试写入数据库节点forselselve({ "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')" } } } } )并且他们的电子邮件以foobar结尾.COM&#34;

但是,指出了一个问题:任何Web客户端都可以在将消息发送到Firebase之前轻松更改其电子邮件(使用开发控制台)。因此,当存储到Firebase中时,我们无法信任用户条目的数据。

我认为我们唯一可以信任的是规则中的$user_id === auth.uid对象。 Firebase的后端填充了auth个对象。不幸的是,auth对象不包含电子邮件地址。

为了记录,我以这种方式插入我的用户:

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's 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 }); 的值(例如,使用DevTools)。

答案 2 :(得分:1)

以下代码在我的数据库中工作正常,我已设置规则,只有我公司的电子邮件才能读取和写入我的firebase数据库的数据。

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


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

答案 3 :(得分:1)

这应适用于任何受Frank van Puffelen的启发而寻求Cloud Firestore选项的用户。

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
    // Allows all users to access data if they're signed into the app with an email of the domain "company.com"
      allow read, write: if request.auth.uid != null && request.auth.token.email.matches(".*@company.com$");
    }
  }
}

答案 4 :(得分:0)

适用于我的代码。

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 :(得分:0)

对于真的不想使用未经验证的帐户登录的任何人。可能很脏,但是非常有效。

这是我的解决方法(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));