当前位置: 首页 > 知识库问答 >
问题:

在不违反RESTful原则的情况下在Angular中进行身份验证和授权的最佳实践?

段干恺
2023-03-14

我已经读了很多关于REST和Angular的身份验证和授权的文章,但我仍然觉得我没有一个很好的解决方案来解决我希望做的事情。作为一些背景,我计划在AngularJS中构建一个应用程序,我想支持:

  1. 宾客访问受限

对REST API的所有调用都需要通过SSL进行。我希望在不违反RESTful原则的情况下构建应用程序,即不将会话状态存储在服务器上。当然,无论在客户端对授权做什么,都必须在服务器端加强。由于我们需要在每个请求中传递整个状态,我知道我需要传递某种令牌,以便接收REST请求的后端服务器能够对调用进行身份验证和授权。

话虽如此,我的主要问题是关于身份验证——这里的最佳实践是什么?似乎讨论了很多不同的方法,以下是我发现的几个:

  • http://broadcast.oreilly.com/2009/12/principles-for-standardized-rest-authentication.html

有人问了一个类似的问题(AngularJS最佳实践应用程序认证),但除非我误解了答案,否则这似乎意味着应该使用服务器会话,这违反了RESTful原则。

我对亚马逊AWS和乔治·里斯文章的主要担忧是,它似乎假设消费者是一个程序,而不是最终用户。可以提前向程序员发布共享秘密,然后程序员可以在这里使用它对调用进行编码。这里的情况并非如此-我需要代表用户从应用程序调用REST API。

这种方法是否足够?假设我有一个会话资源:

后 /api/session

为用户创建新会话

要创建会话,您需要发布一个包含“用户名”和“密码”的JSON对象。

{
    "email" : "austen@example.com",
    "password" : "password"
}

卷曲实例

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-创建,建立新会话
  • 400-错误请求,JSON对象无效或所需信息丢失
  • 401-未经授权,检查电子邮件/密码组合
  • 403-访问被拒绝,禁用帐户或许可证无效

为了清楚起见,我省略了HATEOAS的细节。在后端,将有一个新的、有限持续时间的会话密钥创建并与用户关联。对于后续请求,我可以将其作为HTTP标头的一部分传递:

Authorization: MyScheme 520138ccfa4634be08000000 

然后,后端服务器将负责从请求中消化这些内容,查找关联用户并执行请求的授权规则。它也应该更新会话的到期时间。

如果所有这些都是通过SSL发生的,那么我是否为我应该防范的任何类型的攻击敞开了大门?您可以尝试猜测会话密钥并将它们放在头中,因此我想我可以在会话密钥中附加一个用户GUID,以进一步防止暴力攻击。

我已经有好几年没有积极编程了,我刚刚回到这里。如果我迟钝或不必要地重新发明轮子,只是希望根据我迄今为止的阅读,让社区运行我的想法,看看它们是否通过石蕊测试,我深表歉意。

共有3个答案

司徒炎彬
2023-03-14

这个问题很好地总结了我对REST的理解

训练真的违反了宁静吗?

如果您在会话中存储令牌,您仍在服务器端创建状态(这是一个问题,因为该会话通常只存储在一个服务器上,这可以通过粘性会话或其他解决方案来缓解)。

我想知道你创建RESTful服务的理由是什么,因为这可能不是一个大问题。

如果您在每个请求的正文中发送一个令牌(因为所有内容都是用SSL加密的,这没关系),那么您可以让任意数量的服务器(负载平衡)为请求提供服务,而不需要事先了解任何状态。

长话短说,我认为以RESTful实现为目标是一个很好的目标,但是当涉及到身份验证和验证授权时,纯粹的无状态肯定会增加一层复杂性。

到目前为止,我已经开始考虑到REST来构建我的后端,制作有意义的URI并使用正确的HTTP谓词,但为了身份验证的简单性(当不使用多个服务器时),仍然在会话中使用令牌。

我通读了你发布的链接,AngularJS one似乎只关注客户端,在那篇文章中似乎没有明确提到服务器,他确实链接到了另一个(我不是节点用户,所以如果我的解释有误,请原谅我),但服务器似乎依赖于客户端来告诉它它的授权级别,这显然不是一个好主意。

鲁炳
2023-03-14

这是一篇关于用角构建的身份验证和登录服务的令人难以置信的文章。

https://medium.com/opinionated-angularjs/7bbf0346acec

戎永福
2023-03-14

当有人询问REST身份验证时,我遵从亚马逊网络服务,基本上建议“这样做”。为什么啊?因为,从“群众智慧”的角度来看,AWS解决了这个问题,被大量使用、大量分析和审查,这些人比大多数人更了解和关心什么是安全请求。安全是一个“不重新发明轮子”的好地方。就“站在肩膀上”而言,你可以做得比AWS更差。

现在,AWS不使用令牌技术,而是使用基于共享机密和有效载荷的安全哈希。它可以说是一个更复杂的实现(包括所有的规范化过程等)。)。

但它起作用了。

缺点是,它要求你的应用程序保留用户共享的秘密(即密码),而且还要求服务器通过密码的纯文本版本访问该秘密。这通常意味着密码被加密存储,然后根据需要解密。这使得服务器端的密钥管理和其他事情比安全哈希技术更加复杂。

当然,任何令牌传递技术最大的问题是中间人攻击和重播攻击。自然,SSL主要缓解了这些问题。

当然,你也应该考虑OAuth家族,它们有自己的问题,特别是互操作性,但如果这不是主要目标,那么这些技术肯定是有效的。

对于你的申请来说,代币租赁不是什么大事。您的应用程序仍需要在租约期限内运行,或能够续订租约。为了做到这一点,它需要保留用户凭证或重新提示他们输入凭证。只需将令牌视为一级资源,就像其他任何资源一样。如果可行,尝试将一些其他信息与请求关联,并将其捆绑到令牌(浏览器签名、IP地址)中,以强制执行某些局部性。

您仍然会遇到(潜在的)重播问题,同一请求可以发送两次。在典型的哈希实现中,时间戳是签名的一部分,可以包含请求的生命周期。在这种情况下,解决方法不同。例如,每个请求都可以使用序列ID或GUID发送,您可以记录请求已经播放,以防止再次发生。不同的技术。

 类似资料:
  • 问题内容: 我已经阅读了很多关于REST和Angular身份验证和授权的SO线程,但是我仍然不觉得自己对自己想做的事情有很好的解决方案。对于某些背景,我打算在AngularJS中构建一个我想支持的应用程序: 访客访问受限 身份验证后,基于角色的应用程序访问 通过API进行身份验证 要求对REST API的所有调用都必须通过SSL进行。我想在不破坏RESTful原则的情况下构建应用程序,即不将会话状

  • 在REST spring Boot中对用户进行授权和身份验证的最佳实践是什么? 我正在构建一个带有标准页面+REST API的移动应用程序。我看了很多关于Spring Security性的文章,基本上大多数都采用了某种fitler方法,允许或阻止REST调用。然而,在我的例子中,我有一些基于用户是谁的身份验证逻辑。例如,有一个API可以更新用户信息,用户可以更新自己,但不能更新其他人。最初我想使用

  • 问题内容: 我正在使用javax.mail用Java发送邮件。现在,项目概念的一部分已更改,我必须发送未经身份验证的邮件。我将不得不更改我的createSession()方法: 很明显,我应该更改为,但是我还应该更改什么? 问题答案: 我认为,就足够了。

  • 问题内容: 我一直在努力用Spring-Security 正确实现Stomp(websocket) 身份验证 和 授权 。 为了后代,我将回答我自己的问题以提供指导。 问题 Spring WebSocket文档(用于身份验证)看起来不清楚ATM(IMHO)。而且我不明白如何正确处理 身份验证 和 授权 。 我想要的是 使用登录名/密码对用户进行身份验证。 防止匿名用户通过WebSocket连接。

  • 我正在实现一个基于Spring Data REST的应用程序,我想知道是否有一种优雅的方法可以使用此框架或相关框架来实现身份验证和授权规则。 对REST服务器的所有HTTP请求都必须带有身份验证标头,我需要检查它们并根据HTTP方法和经过身份验证的用户与所请求资源的关联来决定是否授权。例如,(该应用程序是电子学习系统的REST服务器),讲师只能访问他们自己的课程部分,学生只能访问他们订阅的课程部分