【发布时间】:2015-04-22 19:55:01
【问题描述】:
我正在寻找一种解决方案,允许首次在 Firebase 中创建数据,然后限制对该数据的所有者(或管理员)的访问。从本质上讲,我已经为一个企业创建了一个注册流程,它在 Firebase 中创建了一个用户以及该企业的关联用户。不幸的是,根据我当前的架构和安全规则,我收到了permission_denied 错误。这是我当前的架构,它是由 EmberFire 使用 business 和 employee 模型之间的 hasMany belongsTo 关系生成的:
+ businesses
+ business_id (generated by EmberFire)
- name
+ employees
- employee_id
- employee_id
+ employees
+ employee_id (generated by Firebase's auth system)
- first name
- last name
- business_id
- role (ex: 99 for admin)
这是我的安全规则:
{
"rules": {
"businesses": {
// allows only administrators of the business to read and write business data
"$business_id": {
".read": "root.child('employees/' + auth.uid + '/business').val() === $business_id && root.child('employees/' + auth.uid + '/role').val() === 99",
".write": "root.child('employees/' + auth.uid + '/business').val() === $business_id && root.child('employees/' + auth.uid + '/role').val() === 99"
}
},
"employees": {
// only allow employees to read/write their own data or the admin of the business they belong to
"$employee_id": {
".read": "auth.uid === $employee_id || (root.child('employees/' + auth.uid + '/role').val() === 99 && root.child('businesses/' + (root.child('employees/' + auth.uid + '/business').val()) + '/employees/' + $employee_id).exists())",
".write": "auth.uid === $employee_id || (root.child('employees/' + auth.uid + '/role').val() === 99 && root.child('businesses/' + (root.child('employees/' + auth.uid + '/business').val()) + '/employees/' + $employee_id).exists())"
}
}
}
}
任何人都可以推荐一组更新的安全规则/架构,以允许在注册期间最初创建数据,然后只有该数据的所有者/管理员可以访问?
注意:我目前正在运行 Firebase 2.2.4 和 EmberFire 1.4.4。
提前致谢, 詹姆斯
更新
这是注册过程中使用的代码:
// first, create the user account to be the admin of the business
_this.firebase.createUser({
email: _this.get('email'),
password: _this.get('password')
}, function(error, userData) {
if (error) {
flashMessages.warning(error);
} else {
// authenticate the user and log them in
_this.get('session').authenticate('authenticator:firebase', {
'email': _this.get('email'),
'password': _this.get('password')
}).then(function() {
// create the business record
var business = _this.store.createRecord('business', {
name: _this.get('businessName')
});
// create the employee record and associate the firebase uid
var employee = _this.store.createRecord('employee', {
id: userData.uid,
firstName: _this.get('firstName'),
lastName: _this.get('lastName'),
});
// add the employee<->business relationship
business.get('employees').then(function(employees) {
employees.addObject(employee);
});
// save the records to Firebase
employee.save().then(function() {
business.save();
});
}).catch(function(error) {
flashMessages.warning(error);
});
}
});
此外,下面是说明我所描述内容的数据快照:
【问题讨论】:
-
嘿,James,append only 的简单方法是我们的 firechat 应用程序在此处的操作方式:github.com/firebase/firechat/blob/master/rules.json#L11。关键是这块:
".write": "!data.exists()". -
感谢您的回复。那有点奏效了。我的
business模型有一个姓名和上面提到的员工列表。添加!data.exists()后,它成功创建了business节点employees,但name未写入,我收到以下错误:update at /businesses/-JnY-AR9vTMjw9Q27BUB failed: permission_denied。经过一些测试,我发现如果我删除businessemployee关系,name被写入并且我没有错误。这几乎就像 EmberFire 发出了两个写请求,这会使规则无效?上面添加了代码。 -
我看到@tstirrat 刚刚评论了相关的 Github 问题。上下文链接github.com/firebase/emberfire/issues/246
标签: javascript firebase firebase-security emberfire