2013-02-03 47 views
39

由于需要执行一些服务器端代码 - 主要是发送电子邮件,我决定使用Nodejs & Express作为服务器端元素以及Firebase来保存数据 - 部分来自学习体验。使用NodeJs与Firebase - 安全

我的问题是在使用简单电子邮件&密码API进行身份验证时使用客户端Firebase库和Nodejs库的最佳方法。如果我执行身份验证客户端并随后在NodeJS端调用不同的路由,那么该请求中的用户身份验证将在请求中进行。在Node中验证用户的方法是什么?

我假设的一种方法是从firebase获取当前用户的用户名&密码,然后将这些密码发布到NodeJS,然后使用服务器上的firebase安全API进行测试。

回答

56

这里的问题基本上是您需要安全地向您的NodeJS服务器传达谁是客户端身份验证的Firebase。有几种方法可以解决这个问题,但最简单的方法可能是让所有客户端都通过Firebase本身进行NodeJS通信。

因此,不要让客户端击中由您的NodeJS服务器提供服务的REST端点,而是让客户端写入您的NodeJS服务器正在监视的Firebase位置。然后,您可以使用Firebase安全规则来验证客户端写入的数据,并且服务器可以信任它。例如,如果你想让用户可以通过你的应用程序发送任意电子邮件(你的NodeJS服务器负责实际发送电子邮件),你可以有一个/ emails_to_send位置,其规则如下:

{ 
    "rules": { 
    "emails_to_send": { 
     "$id": { 
     ".write": "!data.exists() && newData.child('from').val() == auth.email", 
     ".validate": "newData.hasChildren(['from', 'to', 'subject', 'body'])" 
     } 
    } 
    } 
} 

然后在客户端,你可以这样做:

ref.child('emails_to_send').push({ 
    from: '[email protected]', 
    to: '[email protected]', 
    subject: 'hi', 
    body: 'Hey, how\'s it going?' 
}); 

而在你的代码的NodeJS,你可以调用.auth()与你的火力地堡秘密(这样你就可以读取和写入的一切),然后执行:

ref.child('emails_to_send').on('child_added', function(emailSnap) { 
    var email = emailSnap.val(); 
    sendEmailHelper(email.from, email.to, email.subject, email.body); 

    // Remove it now that we've processed it. 
    emailSnap.ref().remove(); 
}); 

这将是最简单也是最正确的解决方案。例如,如果用户通过Firebase注销,他们将无法再写入Firebase,因此他们将无法再让您的NodeJS服务器发送电子邮件,这很可能是您想要的行为。这也意味着,如果您的服务器暂时关闭,当您开始备份时,它会“赶上”发送电子邮件,一切都将继续有效。

+2

这是伟大的意见 - 谢谢。 也许firebase文档可以扩展到包含这种架构建议。 – markbarton

+3

好点。我会看看我们能做些什么。 :-) –

+0

这样,电子邮件发送的错误处理也应该通过Firebase完成...... FYI – tomericco

0

以上看起来像是一种迂回的做事方式,我会用https://www.npmjs.com/package/connect-session-firebase之类的东西,并保留firebase作为模型,通过express处理所有路线。如果您的快递服务器正在呈现模板而不仅仅是作为JSON API运行,则更容易。