Firebase作为AngularJS的后端

时间:2016-03-14 02:46:00

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

我很困惑。我开始在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),但这对我来说似乎有点暗。我不习惯将这些敏感数据暴露给客户端。

我很抱歉,如果我在这里看起来有点愚蠢,但我会很感激帮助。

1 个答案:

答案 0 :(得分:7)

TL; DR - 跳到"答案"如果您不需要firebase中用户处理的基本概念

,请参阅下面的内容

基本概念

我有非常相似的问题,我也来自常规后端(但在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,它将分成很多东西,最终会出现在不同的地方:

1)帐户方法

让我们从最简单的开始。 Firebase只关注所有这些。只需查看文档,了解sign upsign outreset passworddelete account以及您需要的任何其他方法。所有这些都是从前端直接完成的。

2)验证数据

登录后,如果您在前端执行 Auth.getAuth(),您将基本上get an authData object(或只是 auth ) :

  • 用户ID( authData.uid
  • 提供商使用了类似密码'或者' facebook' ( authData.provider )。
  • A"提供商资料"。该属性与提供程序名称相同( auth [auth.provider] )。

providerProfile是一个包含提供者信息的对象。如果the provider is password,个人资料只包含电子邮件,profileImageURL和isTemporaryPassword。如果the provider was facebook(或其他社交网络),您将从用户的Facebook帐户中获取大量内容。

所有这些都由firebase 内部处理,当用户登录时免费提供,因此您不必存储任何。但请记住,您无法直接编辑任何内容,因为它不在数据库中。在Firebase信息中心中,您的数据库中会出现,但您可以在"登录&验证"标签

3)用户信息(不要称之为'个人资料'以避免混淆)

假设您需要以下信息:

  • 不在providerProfile中,因为您将自己生成它(例如' favoriteColor')
  • 不在至少一个提供商中,但您希望每个人都拥有它(例如' displayName',这是not in the 'password' provider
  • 您希望能够更改它(保留自定义imageProfileURL,不一定是Facebook或gravatar&#39)

在这种情况下,您只需像存储数据库中的任何其他数据一样存储它。例如,您的数据库可能有一个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
      },
    ...
    }
  }
} 

4)秘密的东西

这与上面的例子非常相似。只需使用不同的安全规则添加另一个在根级别的对象。

{
  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不会运行任何后端代码(至少目前为止)。对于更复杂的应用程序,您可能需要一些服务器端代码,主要用于运行因某些原因您不想要或无法在前端运行的内容,例如:

  • 需要安全API令牌(如付款或第三方api)的东西
  • 不适合前端的密集型任务(压缩视频)。 Firebase Queue非常适合。
  • 复杂的数据库查询不能handled by firebase alone。如果过于复杂,您可能需要elasticSearch
  • 之类的内容

请记住,即使您需要一个后端,它也会拥有曾经拥有的代码的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个半月后没有回答,你应得的。快乐的火焰喷射。