REST API登录模式


181

我正在创建一个REST api,紧紧遵循apigee建议,使用名词而不是动词,url中烘焙的api版本,每个集合两个api路径,GET POST PUT DELETE用法等。

我正在使用登录系统,但是不确定用于登录用户的正确REST方式。我目前不在安全性方面,只是在登录模式或流程方面。(稍后,我们将添加2步oAuth,以及HMAC等)

可能的选择

  • 张贴到类似的东西 https://api...com/v1/login.json
  • 放置到类似 https://api...com/v1/users.json
  • 我还没有...

用于登录用户的正确REST风格是什么?


9
那是响应格式。.json告诉服务器以json响应,.xml告诉服务器以xml格式响应。而是使其成为?后面的可选参数。 blog.apigee.com/detail/...
斯科特Roepnack

28
从未见过仅在标头中对URL进行内容协商的情况。在URL上,这意味着您将失去缓存等方面的好处。
奥德

10
@ScottRoepnack,那么您应该考虑AcceptHTTP标头。
亚历山德罗·冯杜斯科洛

2
@Oded如果您使用Accept标头,则还会有一个Vary: Accept,因此不会影响缓存。扩展的连接之前已有讨论 ; 我会同意Shonzilla的回答。
cmbuckley 2012年

2
@Oded-我不明白。如果在URL中指定内容类型(作为查询路径的.json后缀或type = json查询参数),为什么会失去缓存的好处?在这种情况下,“您”是谁?谁会失去缓存利益?在我看来,无论查询路径或参数中的内容如何,​​都可以缓存任何查询的结果。
Cheeso

Answers:


138

Roy T. Fielding和Richard N. Taylor提出的现代Web体系结构的原则设计,即来自所有REST术语的工作序列,都包含客户端-服务器交互的定义:

所有REST交互都是无状态的。也就是说,每个请求都包含连接器理解该请求所需的所有信息,而与之前的任何请求无关

此限制完成四个功能,在这种特殊情况下,第一个和第三个很重要:

  • 第一无需连接器即可保留请求之间的应用程序状态,从而减少了物理资源的消耗并提高了可伸缩性;
  • 第三:它允许中介独立地查看和理解请求,这在动态地重新安排服务时可能是必需的;

现在让我们回到您的安全案例。每个请求都应包含所有必需的信息,并且授权/身份验证也不例外。如何实现呢?从字面上看,每个请求都通过电线发送所有必需的信息。

如何将其归档的示例之一是基于哈希的消息认证代码HMAC。实际上,这意味着将当前消息的哈希码添加到每个请求。通过密码哈希函数结合秘密密码密钥计算的哈希码。加密哈希函数是预定义的,或者是按需代码 REST概念(例如JavaScript)的一部分。 服务器应将秘密密钥作为资源提供给客户端,客户端使用它来为每个请求计算哈希码。

HMAC实现的示例很多,但我希望您注意以下三个:

在实践中如何运作

如果客户端知道密钥,则可以使用资源进行操作。否则,他将被临时重定向(状态码307临时重定向)进行授权并获取密钥,然后将其重定向回原始资源。在这种情况下,无需事先知道(即某处的硬编码)授权客户端的URL是什么,并且可以随时间调整此架构。

希望这可以帮助您找到合适的解决方案!


23
MAC系统是为了证明消息authencity和防止篡改-它无关,与用户认证
YRK

1
添加了示例之一,即如何在不事先知道“ 登录URL ”的情况下处理用户/客户端身份验证
Akim 2012年

下面是与REST服务无国籍身份验证的例子另外两个漂亮的文章:blog.jdriven.com/2014/10/... technicalrex.com/2015/02/20/...
弗拉基米尔·罗日科夫

41

TL; DR登录不是实现API安全所需的每个请求的组件,而是身份验证。

通常不谈论安全性就很难回答有关登录的问题。使用某些身份验证方案,就没有传统的登录名。

REST并没有规定任何安全规则,但是实践中最常见的实现是具有三向身份验证的OAuth(正如您在问题中提到的)。本身没有登录,至少每个API请求都没有。使用三向身份验证,您只需使用令牌。

  1. 用户批准API客户端并授予许可以长期令牌的形式发出请求
  2. Api客户端通过使用长期令牌来获取短期令牌。
  3. Api客户端会在每个请求中发送短期令牌。

该方案为用户提供了随时撤消访问权限的选项。我见过的几乎所有公开可用的RESTful API都使用OAuth来实现。

我只是不认为您应该从登录的角度来考虑问题(和问题),而应该考虑总体上保护API。

有关一般情况下有关REST API身份验证的更多信息,您可以查看以下资源:


是的,OAuth!非常简单的答案,应该是公认的答案,恕我直言。
莱维特

26

REST哲学的很大一部分是在设计API时尽可能多地利用HTTP协议的标准功能。将这一原理应用于身份验证后,客户端和服务器将利用API中的标准HTTP身份验证功能。

登录屏幕非常适合人类用户使用情况:访问登录屏幕,提供用户/密码,设置cookie,客户端在以后的所有请求中都提供该cookie。不能期望使用Web浏览器的人为每个单独的HTTP请求提供用户ID和密码。

但是对于REST API,登录屏幕和会话cookie并不是严格必需的,因为每个请求都可以包含凭据而不会影响人类用户。如果客户在任何时候都不合作,401则可以给出“未经授权”的响应。 RFC 2617描述了HTTP中的身份验证支持。

TLS(HTTPS)也将是一个选项,并且将通过验证另一方的公钥,在每个请求中都允许对服务器进行客户端身份验证(反之亦然)。另外,这为获得奖金提供了保障。当然,进行通信之前必须进行密钥对交换。(请注意,这特别是关于使用TLS识别/验证用户。使用TLS / Diffie-Hellman来保护通道始终是一个好主意,即使您没有通过用户的公共密钥来识别该用户也是如此。)

一个示例:假设OAuth令牌是您的完整登录凭据。客户端获得OAuth令牌后,可以在每个请求的标准HTTP身份验证中将其作为用户ID提供。服务器可以在首次使用时验证令牌,并以每个请求更新的生存时间来缓存检查结果。401如果未提供,则需要身份验证的任何请求都将返回。


1
“由于每个请求都可以包含凭据而不会影响人类用户”发明了三向身份验证和OAuth,因为引号中的内容很糟糕。如果在服务器上没有机制的情况下为每个请求提供凭据,那么如果不使用SSL,则将是不安全的。
Slavo 2012年

1
只要有用户概念,就必须将某些内容从客户端传递到服务器,以识别哪个用户。在这里,OAuth令牌当然可以充当“凭据”,而不是实际的用户/密码组合。使用TLS保护通道肯定是一件好事,但这几乎是没有意义的。即使您使用Cookie,每一次请求仍会使用cookie头而不是身份验证头将某种令牌发送到服务器。
wberry 2012年

而且,如果您出于某种原因未使用TLS或OAuth,那么每次发送用户/密码真的比只发送一次更糟吗?如果攻击者可以获得用户名/密码,则攻击者还可能获得会话cookie。
wberry

cookie和作为凭据的身份验证标头之间的区别在于cookie始终与特定域相关联。这意味着,当API收到Cookie时,它便知道它来自何处(之前是由同一域编写的)。使用标头,您将永远不知道,并且您必须为此执行特定检查。总的来说,我同意,它们都是凭据,但是我认为传递凭据不是登录。登录是打开门的积极动作。在三向身份验证的情况下,只有客户端的第一个批准才可以登录。
Slavo 2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.