[英]Firebase Realtime Database rules not working in frontend
具体的TLDR:规则".read": "auth != null && data.child('userEmail').val() === root.child('users').child(auth.uid).child('email').val()"
应该在应用程序中按预期工作。
我已经按照文档和规则操场进行了测试,所以我认为这可能与我进行身份验证的方式有关? 我将在下面提供信息,希望有人能尽快回答。
实时数据库结构:
"db-name": {
"units": {
0: {
"serial": "002",
"userEmail": "s@gmail.com"
},
1: {
"serial": "001",
"userEmail": "r@gmail.com"
}
},
"users": {
"R6nlZ...": {
"email": "r@gmail.com"
},
"qwerty...": {
"email": "s@gmail.com"
}
}
}
规则对象:
{
"rules": {
// ".read": "now < 1604037600000", // 2020-10-30
// ".write": "now < 1604037600000", // 2020-10-30
"units": {
".indexOn": "userEmail",
"$key": {
".read": "auth != null && data.child('userEmail').val() === root.child('users').child(auth.uid).child('email').val()",
".write" : "auth != null && data.child('userEmail').val() === root.child('users').child(auth.uid).child('email').val()"
}
},
"users": {
"$uid": {
".read": "$uid === auth.uid",
".write": "$uid === auth.uid"
}
}
}
}
规则测试:模拟类型:读取 位置:https:db-name.firebaseio.com/units/1 经验证:是 提供者:匿名 UID:R6nlZ... 结果:允许模拟读取
如果我试图让/units/0
我得到否认这是我所期望的,因为这是一个unit
,目前auth'd用户没有权限查看。
现在,如果我使用纯 javascript 执行此操作,则不会得到与在 Firebase 控制台中的规则操场中所做的相同的结果。
<!-- Add the entire Firebase JavaScript SDK -->
<script src="https://www.gstatic.com/firebasejs/7.24.0/firebase.js"></script>
<script>
// import * as firebase from "firebase";
var firebaseConfig = {
apiKey: "...",
authDomain: "...",
databaseURL: "...",
projectId: "...",
storageBucket: "...",
messagingSenderId: "...",
appId: "..."
};
// Initialize Firebase
firebase.initializeApp(firebaseConfig);
var email = 'r@gmail.com';
var password = '123456';
// Sign in existing user
firebase.auth().signInWithEmailAndPassword(email, password).then(function() {
console.log('Signed in as: ' + firebase.auth().currentUser.email);
var dbUnits = firebase.database().ref().child('units').orderByChild('userEmail').equalTo(firebase.auth().currentUser.email);
var getUnitsDetails = function() {
return dbUnits.once('value').then(function(snapshot) {
snapshot.val() ?
Object.entries(snapshot.val()).map((unit) => {
return (
console.log('Serial number of unit: ' + unit[1].serial + ' & Owner of unit: ' + unit[1].userEmail)
)
})
:
console.log('no units found for that user bro')
})
}
console.log(getUnitsDetails());
}).catch(function(error) {
console.log(error);
});
当我在粘贴的规则中设置了 Firebase 权限时,用户r@gmail.com
看不到任何单位。 如果我让读取权限完全打开(不是我想要的),那么该用户可以看到他们的单位。
对我来说这没有意义,因为我认为auth.uid
是 Firebase 在用户登录时可以看到的内容,无论他们使用什么登录类型。
您的规则不允许此查询:
firebase.database().ref().child('units').orderByChild('userEmail').equalTo(firebase.auth().currentUser.email);
要使此查询起作用,用户需要对/units
具有读取权限。 由于您没有在/units
上声明任何.read
规则,因此查询被拒绝。
您似乎认为规则会过滤数据以仅返回用户应该有权访问的数据,但这不是它们的工作方式。 正如 Firebase 文档所说: 规则不是过滤器。
但是安全规则可以与查询结合使用,以安全地允许查询数据。
在你的场景中,看起来像:
{
"rules": {
"units": {
".read": "auth.uid != null &&
query.orderByChild == 'userEmail' &&
query.equalTo == auth.token.email"
...
现在您的查询将被允许,而/users
其他/更广泛的读取将被拒绝。
"$key": {
".read": "auth !== null && root.child('users').hasChild(auth.uid)",
".write" : "auth !== null && root.child('users').hasChild(auth.uid)"
}
这样写的任何存在于用户集合中的用户都可以访问“单位”
或者,您可以使用该用户的 uid 进行收集,并将密钥与他的 uid 匹配以进行访问
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.