快速背景:
与Jstful API服务器对话的完整Javascript SPA AngularJS客户端。我正在尝试为API服务器制定最佳身份验证。客户端将拥有角色,我不担心用户是否可以看到客户端区域是不允许的,因为服务器应该是气密的。
身份验证流程:
问题:
任何建议或示例都将不胜感激。
答案 0 :(得分:4)
我目前正在研究类似的情况,使用angularjs + node作为REST API,使用HMAC进行身份验证。
我正在努力解决这个问题,所以我的调整可能会随时改变。这是我的。任何愿意在这方面打洞的人,我也欢迎:
通过https
服务器(在我的情况下是node.js + express)向经过身份验证的用户发回临时通用私钥。此密钥是用户将用于签署HMAC客户端的密钥,并且存储在浏览器上的LocalStorage中,而不是cookie(因为我们不希望它在每个请求上来回传递)。
然后将密钥存储在浏览器的LocalStorage中(如果不支持LocalStorage,则应用程序实际上会显示您的浏览器太旧的页面,甚至可以尝试登录)。
然后,除初始身份验证之外的所有请求都会发送三个自定义标头:
Auth-Signature
:username
+ time
+ request.body
的HMAC(在我的情况下request.body
是请求的JSON.stringify()
代表vars)使用本地存储的密钥签名Auth-Username
:username
X-Microtime
:客户端生成HMAC时的unix时间戳<然后服务器检查X-Microtime
标头,如果X-Microtime
和now
之间的差距大于10秒,则将请求作为潜在的重播攻击丢弃并抛出回到401。
然后,服务器使用与客户端相同的序列生成自己的HMAC,Auth-Username
+ X-Microtime
+ req.body
使用节点内存中的6小时私钥。< / p>
如果HMAC相同,请信任该请求,如果没有,请401.如果我们需要处理API上任何特定用户的信息,我们会有Auth-Username
标题。
所有这些通信都是通过HTTPS实现的。
在每次成功请求后,必须将密钥返回给客户端,以使客户端与动态密钥保持同步。这是有问题的,因为它与cookie基本相同。
您可以将密钥设置为静态且永不更改,但这似乎不太安全,因为密钥永远不会过期。您还可以为每个用户分配一个密钥,该密钥在登录时返回给客户端,但是您仍然必须对每个请求进行用户查找,也可以在此时使用基本身份验证。
所以,在对我自己做了一些测试之后,我决定使用后端代理到我的REST API仍然使用HMAC。
Angular连接到同域后端,后端从上面运行HMAC过程,存储在此代理上的私钥。在同一个域上拥有这个允许我们阻止战队。
成功验证后,angular只获取一个标志,我们将登录状态存储在LocalStorage中。没有钥匙,但是可以识别用户并且可以公开的东西。对我来说,这个存储值的存在决定了用户是否登录。我们在注销时删除localStorage,或者我们决定使他们的“会话”无效。
从angular到同一个域代理的后续调用包含用户标头。代理检查用户标题(只能由我们设置,因为我们阻止了跨站点访问),如果没有设置则返回401,否则只是将请求转发到API,但HMAC就像上面一样。 API将响应传递回代理,从而返回到角度。
这允许我们将私有位保留在前端之外,同时仍然允许我们构建一个可以快速进行身份验证的API,而无需在每个请求上调用DB,并保持无状态。它还允许我们的API提供其他接口,如本机移动应用程序。移动应用程序只会与私钥捆绑在一起,并为每个请求运行HMAC序列。