AngularJS SPA和RestfulAPI服务器安全性

时间:2014-02-03 23:50:43

标签: javascript angularjs authentication cookies ssl

快速背景:

与Jstful API服务器对话的完整Javascript SPA AngularJS客户端。我正在尝试为API服务器制定最佳身份验证。客户端将拥有角色,我不担心用户是否可以看到客户端区域是不允许的,因为服务器应该是气密的。

身份验证流程:

  • 用户发布用户名和密码,例如/ api / authenticate
  • 如果用户服务器生成api令牌(字段或md5的sha哈希)以及其他一些元数据确定角色要在1)回复后传回。
  • 令牌存储在会话cookie中(无exp,仅http,ssl)
  • 身份验证后的每个请求都会获取Cookie中的令牌,并验证这是用户。
  • 服务器上的SSL用户。

问题:

  • 这是保护服务器的最佳方式吗?
  • 我是否需要担心带有SSL的重播攻击?如果有这么好的方法来管理它?
  • 我试图想办法用AngularJS做HMAC安全,但是我不能在javascript客户端上存储私钥。
  • 我最初使用的是http身份验证方法,但每个请求都发送用户名和密码似乎很奇怪。

任何建议或示例都将不胜感激。

1 个答案:

答案 0 :(得分:4)

我目前正在研究类似的情况,使用angularjs + node作为REST API,使用HMAC进行身份验证。

我正在努力解决这个问题,所以我的调整可能会随时改变。这是我的。任何愿意在这方面打洞的人,我也欢迎:

  1. 通过https

  2. 进行用户身份验证,用户名和密码
  3. 服务器(在我的情况下是node.js + express)向经过身份验证的用户发回临时通用私钥。此密钥是用户将用于签署HMAC客户端的密钥,并且存储在浏览器上的LocalStorage中,而不是cookie(因为我们不希望它在每个请求上来回传递)。

    • 密钥存储在nodejs内存中,每六小时重新生成一次,记录生成的最后一个密钥。密钥更改后10秒钟,服务器实际生成两个HMAC;一个用新密钥,一个用旧密钥。这样,在更改密钥时发出的请求仍然有效。如果密钥更改,服务器会将新密钥发送回客户端,以便它可以在LocalStorage中将其刷新。密钥是使用node-uuid生成的UUID的SHA256,使用加密进行哈希处理。输入后,我意识到这可能无法很好地扩展,但无论如何... ...

  4. 然后将密钥存储在浏览器的LocalStorage中(如果不支持LocalStorage,则应用程序实际上会显示您的浏览器太旧的页面,甚至可以尝试登录)。

  5. 然后,除初始身份验证之外的所有请求都会发送三个自定义标头:

    • Auth-Signatureusername + time + request.body的HMAC(在我的情况下request.body是请求的JSON.stringify()代表vars)使用本地存储的密钥签名
    • Auth-Usernameusername
    • X-Microtime:客户端生成HMAC时的unix时间戳<
      li
  6. 然后服务器检查X-Microtime标头,如果X-Microtimenow之间的差距大于10秒,则将请求作为潜在的重播攻击丢弃并抛出回到401。

  7. 然后,服务器使用与客户端相同的序列生成自己的HMAC,Auth-Username + X-Microtime + req.body使用节点内存中的6小时私钥。< / p>

  8. 如果HMAC相同,请信任该请求,如果没有,请401.如果我们需要处理API上任何特定用户的信息,我们会有Auth-Username标题。

  9. 所有这些通信都是通过HTTPS实现的。

    编辑:

    在每次成功请求后,必须将密钥返回给客户端,以使客户端与动态密钥保持同步。这是有问题的,因为它与cookie基本相同。

    您可以将密钥设置为静态且永不更改,但这似乎不太安全,因为密钥永远不会过期。您还可以为每个用户分配一个密钥,该密钥在登录时返回给客户端,但是您仍然必须对每个请求进行用户查找,也可以在此时使用基本身份验证。

    编辑#2

    所以,在对我自己做了一些测试之后,我决定使用后端代理到我的REST API仍然使用HMAC。

    1. Angular连接到同域后端,后端从上面运行HMAC过程,存储在此代理上的私钥。在同一个域上拥有这个允许我们阻止战队。

    2. 成功验证后,angular只获取一个标志,我们将登录状态存储在LocalStorage中。没有钥匙,但是可以识别用户并且可以公开的东西。对我来说,这个存储值的存在决定了用户是否登录。我们在注销时删除localStorage,或者我们决定使他们的“会话”无效。

    3. 从angular到同一个域代理的后续调用包含用户标头。代理检查用户标题(只能由我们设置,因为我们阻止了跨站点访问),如果没有设置则返回401,否则只是将请求转发到API,但HMAC就像上面一样。 API将响应传递回代理,从而返回到角度。

    4. 这允许我们将私有位保留在前端之外,同时仍然允许我们构建一个可以快速进行身份验证的API,而无需在每个请求上调用DB,并保持无状态。它还允许我们的API提供其他接口,如本机移动应用程序。移动应用程序只会与私钥捆绑在一起,并为每个请求运行HMAC序列。