我正在尝试为使用firebase的应用程序设计安全性的最佳方法
基本问题
我们希望用户的数据安全。我们不希望恶意代理能够访问Firebase数据库上的其他用户的私有数据。似乎应该通过firebaseSimpleLogin解决这个问题,但是尽管我们没有看到文档,但我们还没有看到它。
问题细节
我们考虑的解决方案
1。存储user_secret以确保用户具有合法访问权限
#1的问题
2。暂时存储用户密码
#2 问题 - 此方法的问题是用户在登录时容易受到攻击,因为他们的安全信息会存在。
3。使用内置的Firebase安全规则
我们希望有人可以帮助阐明这里的最佳方法,无论是使用我们的想法还是其他途径。非常感谢你的帮助。
答案 0 :(得分:5)
您基本上要求某人为您的应用编写完整的安全架构。如果您在尝试将安全规则应用于这样的复杂结构之前彻底理解安全规则,那会更好。 A good study of the docs from start to end将为您提供一个功能齐全的解决方案。
让我们只关注似乎是核心问题,即您不确定如何使用仅限客户端的解决方案使邀请安全地工作。 (由于能够创建我们自己的令牌所提供的额外火力,node.js解决方案也应该明白这种理解)我会在这里做出很多假设;只需将这些想法应用到您当前的用例中即可。
数据结构:
/invites/$game_id/$uuid/true (a place to store invited users)
/accepted_invites/$gameid/$userid/$uuid/true (a place to store accepted invites)
/games/$game_id (the place we want to invite users into)
/users/$user_id (a place where we put profiles for existing users)
1)当新用户在应用中创建帐户时,请将他们的个人资料写入/ users。安全用户/如下:
"users": {
"$userid": {
".write": "auth.uid === $userid"
}
}
2)要邀请用户,请创建一个uuid,表示一个不可提交的ID,并将其存储在邀请/ $ game_id中。请注意,没有人应该能够阅读此路径。
"invites": {
"$game_id": {
"$invite_id": {
// I can only create an invite for groups I'm a member of
".write": "root.child('games/'+$game_id+'/members/'+auth.uid).exists()",
".validate": "newData.val() === true"
}
}
}
3)要加入游戏,用户必须首先接受访问令牌,证明他们 知道令牌(因为他们无法读取邀请路径)并将令牌链接到他们的 帐户ID。此条目的值是邀请的uuid。
"accepted_invites": {
"$game_id": {
"$user_id": {
".write": "auth.uid === $user_id",
".validate": "root.child('invites/'+$game_id+'/'+newData.val()).exists()"
}
}
}
4)如果用户已经接受邀请或者最初创建并且还没有成员(!data.parent().exists()
规则)
"game": {
"$gid": {
"members": {
"$uid": {
".write": "auth.uid === $uid",
// I can join a group if a) I'm creating it or b) I have accepted an invite
".validate": "!data.parent().exists() || root.child('accepted_invites/'+$gid+'/'+auth.uid).exists()"
}
}
}
}
我们客户端解决方案的另一个增强功能是为邀请分配一个优先级,代表它们何时到期,然后在安全规则中引用该优先级来控制令牌有效的时间。
答案 1 :(得分:0)
由于@Kato的建议,我最终得到了#3的想法。到目前为止,使用内置规则和设计模式的解决方案允许我们避免需要第三方auth服务器。架构的一些示例如下:
"game_detail" : {
"$game_detail" : {
".read" : "data.child('owner').val() === auth.email || root.child('admins').val() === auth.email",
".write" : "newData.child('owner').val() === auth.email || root.child('admins').val() === auth.email"
}
},
然后,使#3成为可能的附加密钥是,除了具有安全规则模式之外,我们还创建了一个通用管理员凭证,匿名用户在登录时可以使用这些凭据来访问数据库并执行必要的跨账户操作。
感谢大家的投入。