加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

Firebase作为AngularJS的后端

发布时间:2020-12-17 17:01:23 所属栏目:安全 来源:网络整理
导读:我很迷茫.我开始在Ionic(仍在学习)和AngularJS开发. 现在,我尝试将Firebase用作应用程序后端.我做了一个facebook身份验证过程,在用户通过身份验证后,会将一个对象添加到数据库中(具有以下属性:名称,用户ID和个人资料图片). 到现在为止还挺好.我仍然不明白Fi
我很迷茫.我开始在Ionic(仍在学习)和AngularJS开发.

现在,我尝试将Firebase用作应用程序后端.我做了一个facebook身份验证过程,在用户通过身份验证后,会将一个对象添加到数据库中(具有以下属性:名称,用户ID和个人资料图片).

到现在为止还挺好.我仍然不明白Firebase是否仅适用于客户端应用程序(作为任何后端服务的替代品),还是专为NodeJS等设计的?

我提出这个问题的原因将作为例子展示:

现在对于黄金问题,让我们说我需要向用户添加单独的“auth_level”(例如)属性.这发生在.js服务(客户端)中.客户端可以访问它,因此他可以更改自己的用户名等内容.

返回{
????‘name’:userData.name,
????‘profilePic’:’http://graph.facebook.com/’userData.id’/ picture’,
????‘userId’:userData.id
};

所以,是的,我知道我可以创建规则来阻止用户说创建一个新对象,但对于上面的例子 – 他已经为了推送到数据库而具有写访问权限.
在我看来,在中间使用Fireabse安全地拥有某种桥(例如NodeJS)的唯一方法,但Firebase失去了“实时”功能,对吧?还是我错了?

所以首先 – 我错过了什么重要的东西吗?

其次,如果这确实不安全,你会推荐其他任何实时后端方法吗?就像使用像MongoDB这样的数据库,并让Node服务器进行所有过滤并通过Web套接字与客户端进行通信.

我对混合移动开发的整个世界都非常陌生,特别是AngularJS,我曾经做过很多PHP(主要是Laravel),但这对我来说似乎有点暗.我不习惯将这些敏感数据暴露给客户端.

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

解决方法

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 up,sign out,reset password,delete account以及您需要的任何其他方法.所有这些都是从前端直接完成的.

2)验证数据

在您登录后,如果您在前端执行Auth.getAuth(),您将基本上执行get an authData object(或仅使用身份验证):

>用户标识(authData.uid)
>提供者使用’密码’或’facebook'(authData.provider).
>“提供者档案”.该属性与提供程序名称相同(auth [auth.provider]).

providerProfile是一个包含提供者信息的对象.如果是the provider is password,该配置文件只有email,profileImageURL和isTemporaryPassword.如果the provider was facebook(或其他社交网络),您将从用户的Facebook帐户中获得大量内容.

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

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

让我们说你想要的信息:

>不在providerProfile中,因为你自己会生成它(比如’favoriteColor’)
>不是至少有一个提供者,但你希望每个人都拥有它(比如’displayName’,即not in the ‘password’ provider)
>你希望能够改变它(保持自定义imageProfileURL,不一定是facebook或gravatar)

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

这里的秘诀是保持数据平稳.我通常会考虑两件事来构建我的数据:我如何保护它(不同的安全级别会转到不同的对象,总之)以及如何在前端检索它.

答案

现在,基本概念已不在考虑之中,我将对您的问题发表评论:

I made a facebook authentication process,and after the user was authenticated an object is added to the database (with these properties: name,user ID and profile picture).

将它们添加到数据库是可选的,您可以在auth对象中免费获得它.

I still don’t understand if Firebase was designed for client-side only applications (as a replacement for any back-end service),or was it designed for stuff like NodeJS too?

对于简单的应用程序,您不需要任何其他内容.您甚至可以使用firebase-hosting服务静态资产(整个前端).但你是对的,firebase不会运行任何后端代码(至少目前为止).对于更复杂的应用程序,您可能需要一些服务器端代码,主要是为了运行因某些原因您不想要或不能在前端运行的东西,例如:

>需要安全API令牌的东西(如付款或第三方apis)
>不适合前端的密集型任务(压缩视频). Firebase Queue非常适合.
>复杂的数据库查询不能是handled by firebase alone.如果太复杂,您可能需要像elasticSearch这样的东西.

请记住,即使您需要后端,它也会拥有曾经拥有的代码的1/3.没有更多的模型,api请求处理,帐户逻辑……减少代码减少错误.

Let’s say that I need to add a separate “auth_level” (for example) property to the user. This occurs in a .js service (client side). The client has access to it,so he can change stuff like his own username.

如上所述,如果添加到具有不同安全规则的其他对象,则不会.他或许可以阅读它,而不是写它.使用规则,您甚至可以选择用户应该能够设置哪些角色以及哪些角色.

Secondly,if this is indeed insecure,do you recommend any other method for real-time back-end? Like using a database such as MongoDB,and having a Node server doing all the filtering and communicating with clients via web sockets.

我们刚刚看到它并不安全.但如果我不得不建议其他实时解决方案,我会告诉你尝试Meteor,它就是你所描述的.因为我不需要,坚持使用firebase,恕我直言,你比其他任何我知道的更好,包括Meteor.

I am very new to the whole world of hybrid mobile development and AngularJS in particular,I used to do a lot of PHP (mainly Laravel) but this just seems a bit dark to me. I am not used to the exposure of such sensitive data to the client-side.

嘿,不要感觉不好,这对你来说不仅仅是新的,而是对整个世界而言……我一直在考虑为firebase / node / angular创建一个可能有用的样板.如果我这样做,我会回来发布一个链接.有一堆基于用户角色的角度路由让我花了一些时间来做对.

Thanks for the response. I understand I can apply some security rules,but when a Firebase entry for a user is created (after facebook authentication) can I enforce pushing the original data from facebook,without being able to push in a different name,for example,by using ONLY AngularJS and 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个半月后没有回答,你应得的.快乐的火焰.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读