在不违反RESTful原则的情况下对Angular进行身份validation和授权的最佳实践?
长时间的粉丝,第一次的海报:)
我已经阅读了很多关于使用REST和Angular进行身份validation和授权的线程,但是我仍然不觉得我有一个很好的解决scheme来实现我所希望的。 对于一些背景,我打算在AngularJS中构build一个我想要支持的应用程序:
- 有限的访客
- 一旦通过身份validation,即可对基于angular色的应用程
- 通过API进行身份validation
所有对REST API的调用都需要通过SSL进行。 我希望在不破坏RESTful原则的情况下构build应用程序,即不会将会话状态保存在服务器上。 当然,无论在服务器端如何进行客户端的授权,都必须加强。 由于我们需要传递每个请求的整个状态,我知道我需要传递某种令牌,以便接收REST请求的后端服务器既可以对呼叫进行身份validation,也可以对其进行授权。
这就是说,我的主要问题是身份validation – 这里最好的做法是什么? 似乎有很多不同的方法讨论,这里只是我发现的几个:
- http://broadcast.oreilly.com/2009/12/principles-for-standardized-rest-authentication.html
- http://frederiknakstad.com/2013/01/21/authentication-in-single-page-applications-with-angular-js/
- http://docs.aws.amazon.com/AmazonS3/latest/dev/RESTAuthentication.html
有一个类似的问题( AngularJS最佳实践应用程序authentication ),但除非我误解了答案,这似乎意味着应该使用服务器会话,这是违反RESTful原则。
我对Amazon AWS和George Reese的文章主要关注的是,似乎认为消费者是一个程序,而不是最终用户。 一个共享的秘密可以提前发给程序员,然后他们可以用它来编码调用。 这不是这种情况 – 我需要代表用户从应用程序调用REST API。
这种方法是否足够? 假设我有一个会话资源:
POST / api /会话
为用户创build一个新的会话
要创build会话,您需要发布一个包含“用户名”和“密码”的JSON对象。
{ "email" : "austen@example.com", "password" : "password" }
curl示例
curl -v -X POST --data '{"username":"austen@example.com","password":"password"}' "https://app.example.com/api/session" --header "Content-Type:application/json"
响应
HTTP/1.1 201 Created { "session": { "id":"520138ccfa4634be08000000", "expires":"2014-03-20T17:56:28+0000" } }
状态码
- 201 – 创build新的会话
- 400 – 错误请求,JSON对象无效或缺less所需的信息
- 401 – 未经授权,检查电子邮件/密码组合
- 403 – 拒绝访问,禁用帐户或许可证无效
为了清晰起见,我将HATEOAS细节略过。 在后端,会有一个新的,持续时间有限的会话密钥创build并与用户关联。 在随后的请求中,我可以将它作为HTTP标头的一部分来传递:
Authorization: MyScheme 520138ccfa4634be08000000
然后,后端服务器将负责从请求中消化这一点,find关联的用户并为请求实施授权规则。 它也许应该更新会话的到期时间。
如果所有这些都是通过SSL进行的,那么我是否会对任何一种我应该保护的攻击敞开大门? 您可以尝试猜测会话密钥并将它们放在标题中,所以我想我可以附加一个用户GUID到会话密钥,以进一步防止暴力攻击。
我已经积极编程已经有几年了,现在我刚刚回到了这里。 道歉,如果我是愚蠢的或不必要的重新发明轮子,只是希望在这里根据我的阅读,由社区运行我的想法,看看他们是否通过了试金石。 预先感谢您提供的任何帮助/build议!
当有人询问REST身份validation时,我遵循amazon web services,基本上build议“这样做”。 为什么? 因为从“人群中的智慧”angular度看,AWS解决了这个问题,被大量使用,深入分析,并且被那些比大多数人知道和关心的东西多得多的人所审查。 而安全是“不要重新发明轮子”的好地方。 就“肩膀站立”而言,你可以做得比AWS差。
现在,AWS不使用令牌技术,而是使用基于共享秘密和有效负载的安全哈希。 这可以说是一个更复杂的实现(所有的标准化过程等)。
但它的作品。
缺点是它需要您的应用程序保留共享密钥的人(即密码),并且还要求服务器有权访问该密码的纯文本版本。 这通常意味着密码被encryption存储,然后根据需要解密。 而且这还邀请了服务器端的密钥pipe理和其他更复杂的安全哈希技术。
当然,任何令牌传递技术的最大问题是中间人攻击和重放攻击。 SSL自然而然地减轻这些。
当然,你也应该考虑OAuth系列,它们有自己的问题,特别是互操作性,但如果这不是主要目标,那么这些技术当然是有效的。
对于你的申请,令牌租约并不是什么大不了的事情。 您的应用程序仍然需要在租赁期限内进行操作,或者可以续约。 为了做到这一点,它将需要保留用户凭证或重新提示他们。 只要将令牌视为第一类资源,就像其他任何东西一样。 如果可行,请尝试将其他信息与请求相关联,并将其绑定到令牌(浏览器签名,IP地址),以强制执行某些地方。
您仍然对(重复)问题持开放态度,即可以发送两次相同的请求。 使用典型的哈希实现,时间戳是签名的一部分,可以包含请求的生命周期。 在这种情况下解决方法是不同的。 例如,每个请求都可以使用序列号或GUID进行发送,并且可以logging请求已被播放以防止再次发生。 不同的技术。
这里是一个令人难以置信的关于authentication和login服务的angular度build立的文章。
这个问题在总结我对REST的理解方面做得很好
会话是否真的违反RESTfulness?
如果在会话中存储令牌,则仍然在服务器端创build状态(这是个问题,因为该会话通常只存储在一台服务器上,可以通过粘滞会话或其他解决scheme来缓解)。
我想知道您创buildRESTful服务的原因是什么,因为这可能不是一个大问题。
如果您在每个请求中发送一个令牌(因为所有内容都使用SSL进行encryption,那么可以),那么您可以拥有任意数量的服务器(负载均衡),而无需事先了解状态。
长话短说我认为针对RESTful实现是一个很好的目标,但是当涉及到validation和validation授权时,纯粹无状态确实会造成额外的复杂层。
到目前为止,我已经开始在REST的基础上构build我的后端,创build有意义的URI并使用正确的HTTP动词,但为了简化身份validation(不使用多个服务器时),仍然在会话中使用一个令牌。
我读通过您发布的链接,AngularJS似乎只关注客户端,似乎并没有明确地解决该文章中的服务器,他链接到另一个(我不是一个Node用户,所以原谅我如果我的解释在这里是错误的),但似乎服务器是依靠客户端来告诉它它具有什么级别的授权显然不是一个好主意。