我很困惑。我开始在Ionic(仍在学习)和AngularJS开发。
现在,我已尝试将Firebase用作应用程序后端。我做了一个facebook身份验证过程,在用户通过身份验证后,会将一个对象添加到数据库中(使用这些属性:名称,用户ID和个人资料图片)。
到目前为止一切顺利。我还是不明白Firebase是专为客户端应用程序设计的(作为任何后端服务的替代品),还是专为NodeJS等设计的?
我提出这个问题的原因将作为例子展示:
现在提出黄金问题,让我们说我需要添加一个单独的" auth_level" (例如)给用户的属性。这发生在.js服务(客户端)中。客户端可以访问它,因此他可以更改自己的用户名等内容。
return {
'name': userData.name,
'profilePic': 'http://graph.facebook.com/' + userData.id + '/picture',
'userId': userData.id
};
所以是的,我知道我可以创建规则来阻止用户说创建一个新对象,但对于上面的例子 - 他已经有了写入权限以便推送到数据库。 在我看来,在中间使用Fireabse安全地拥有某种桥(例如NodeJS)的唯一方法,但Firebase失去了实时"功能,对吗?或者我错了吗?
所以首先 - 我错过了什么重要的东西吗?
其次,如果这确实不安全,您是否推荐其他任何实时后端方法?就像使用像MongoDB这样的数据库,并让Node服务器通过网络套接字进行所有过滤和与客户端通信。
我对混合移动开发的整个世界非常陌生,尤其是AngularJS,我曾经做过很多PHP(主要是Laravel),但这对我来说似乎有点暗。我不习惯将这些敏感数据暴露给客户端。
我很抱歉,如果我在这里看起来有点愚蠢,但我会很感激帮助。
答案 0 :(得分:7)
我有非常相似的问题,我也来自常规后端(但在node.js中)。让我先从一个例子开始(例如,使用js / mongoose,但请耐心等待):
这是用户在常规后端应用中的模型:
var userSchema = new mongoose.Schema({
// 2) Auth Data
userId: ObjectId,
email: String,
password: String,
facebookProfile: Mixed,
// 3) User Info
displayName: String,
favoriteColor: String,
profileImageURL: String,
// 4) Secret Stuff
userRole: String
});
// 1) Account Methods
userSchema.static.createAccount = function (userData) { ... };
userSchema.methods.attemptLogin = function (password) { ... };
userSchema.methods.forgotPassword = function () { ... };
userSchema.methods.resetPassword = function (token, newPassword) { ... };
如果要将上面的示例迁移到firebase,它将分成很多东西,最终会出现在不同的地方:
让我们从最简单的开始。 Firebase只关注所有这些。只需查看文档,了解sign up,sign out,reset password,delete account以及您需要的任何其他方法。所有这些都是从前端直接完成的。
登录后,如果您在前端执行 Auth.getAuth(),您将基本上get an authData object(或只是 auth ) :
providerProfile是一个包含提供者信息的对象。如果the provider is password,个人资料只包含电子邮件,profileImageURL和isTemporaryPassword。如果the provider was facebook(或其他社交网络),您将从用户的Facebook帐户中获取大量内容。
所有这些都由firebase 内部处理,当用户登录时免费提供,因此您不必存储任何。但请记住,您无法直接编辑任何内容,因为它不在数据库中。在Firebase信息中心中,您的数据库中会出现不,但您可以在"登录&验证"标签
假设您需要以下信息:
在这种情况下,您只需像存储数据库中的任何其他数据一样存储它。例如,您的数据库可能有一个userInfo对象,如下所示:
{
userInfo: {
"e0cb8039-deb0-4264-8fde-ca82ece76cb0": {
displayName: "John Snow",
favoriteColor: "black",
profileImageURL: "..."
},
"b84692f-03a9-4f5c-914d-f78d508b4665": {
displayName: "Sansa Stark",
favoriteColor: "red",
profileImageURL: "..."
}
}
}
为了保证此对象的安全,您可以添加以下规则:
{
"rules": {
...
"userInfo": {
"$uid": {
// this 'auth' is exaclty the 'authData' in the example above
".write": "auth.uid === $uid", // only owner can write
".read": "auth !== null" // any authenticated user can read
},
...
}
}
}
这与上面的例子非常相似。只需使用不同的安全规则添加另一个在根级别的对象。
{
userRoles: {
"e0cb8039-deb0-4264-8fde-ca82ece76cb0": "admin",
"ab84692f-03a9-4f5c-914d-f78d508b4665": "client" // not even necessary..
}
和规则
{
"rules": {
...
"userRoles": {
"$uid": {
// only admins can edit roles
".write": "root.child('userRoles').child(auth.uid).val() === 'admin'",
// Users can read their own roles. Admins can read anyones
".read": "auth.uid === $uid ||
root.child('userRoles').child(auth.uid).val() === 'admin'"
},
...
}
}
}
这里的秘诀是保持数据平稳。我通常会考虑两件事来构建我的数据:我如何保护它(不同的安全级别会转到不同的对象,总之)以及如何在前端检索它。
现在,基本概念已不在考虑之中,我会对您的问题发表评论:
我做了一个facebook身份验证过程,在用户通过身份验证后,会将一个对象添加到数据库中(具有以下属性:名称,用户ID和个人资料图片)。
将它们添加到数据库是可选的,您可以在 auth 对象中免费获得它。
我仍然不明白Firebase是专为客户端专用应用程序设计的(作为任何后端服务的替代品),还是专为NodeJS等设计的?
对于简单的应用,您不需要任何其他内容。您甚至可以使用firebase-hosting服务静态资产(整个前端)。但你是对的,firebase不会运行任何后端代码(至少目前为止)。对于更复杂的应用程序,您可能需要一些服务器端代码,主要用于运行因某些原因您不想要或无法在前端运行的内容,例如:
请记住,即使您需要一个后端,它也会拥有曾经拥有的代码的1/3。没有更多的模型,api请求处理,帐户逻辑......减少代码减少错误。
让我们说我需要添加一个单独的" auth_level" (例如)给用户的属性。这发生在.js服务(客户端)中。客户端可以访问它,因此他可以更改自己的用户名等内容。
如上所述,如果添加到具有不同安全规则的其他对象,则不会。他或许可以阅读它,而不是写它。使用规则,您甚至可以选择用户应该为自己设置哪些角色,哪些角色不能。
其次,如果这确实不安全,您是否推荐其他任何实时后端方法?就像使用像MongoDB这样的数据库,并让Node服务器通过网络套接字进行所有过滤和与客户端通信。
我们刚刚看到它并不安全。但是,如果我必须建议其他实时解决方案,我告诉你尝试Meteor,它就是你所描述的。由于我没有必要,坚持使用firebase,恕我直言,除了我所知道的任何其他事情,包括Meteor之外,你的状况要好一些。
我对混合移动开发的整个世界非常陌生,尤其是AngularJS,我曾经做过很多PHP(主要是Laravel),但这对我来说似乎有点暗。我不习惯将这些敏感数据暴露给客户端。
嘿,不要感觉不好,这对你来说不仅仅是新的,而是对整个世界而言......我一直在考虑为firebase / node / angular创建一个可能有用的样板。如果我这样做,我会回来发布一个链接。基于用户角色的一系列角度路由让我花了一些时间来做对。
感谢您的回复。我知道我可以应用一些安全规则,但是当创建用户的Firebase条目时(在facebook身份验证之后),我可以强制从facebook推送原始数据,而无法推送其他名称,例如,仅使用AngularJS和Firebase?
当然可以,但由于您可以直接从前端获取authData,因此您可能不需要。如果你想在数据库中保留它的副本,比方说,因为你需要从某个地方读取用户没有登录的内容,只需使用类似这样的规则:
// The old data has to be empty
// The new data has to be exactly like the user providerProfile
".validate": "!data.exists() &&
newData.val() === auth[auth.provider]"
唷!这是一个(可能是不必要的)长期答案。但是我希望在我第一次出发时能够找到这种想法。文档很棒,但这些例子只是较小的部分,可能很难组合在一起。无论如何,在1个半月后没有回答,你应得的。快乐的火焰喷射。