API端点是否根据用户凭据RESTful和良好的URI设计来区分要返回的资源?

时间:2015-03-12 08:48:56

标签: rest authentication uri restful-url api-design

重要提示

此问题的重点是API端点,用于区分根据谁进行身份验证返回哪些资源,例如Alice获得资源A和B返回,Bob获取资源X和Y.

NOT 关于区分返回的资源的表示。

所有端点都返回资源的JSON表示。

前言

请考虑以下三种潜在的API端点设计,均为用户的thing资源返回。

端点A

GET /things

如果请求提供了<user_x>的身份验证凭据,则会返回thing 特定相关的<user_x>个资源。 例如,验证用户Alice获取资源A和B返回,并且验证用户Bob获取资源X和Y。

因此,不同身份验证用户的响应区别在于返回哪些资源实例, NOT 返回这些实例的哪些信息(即资源表示)。

当身份验证失败时,将返回401响应。

端点B

GET /user/<user_x>/things

端点C

GET /things/?user_id=<user_x>

端点B和C都提供与thing相关的<user_x>资源实例, iff 验证用户有权访问这些thing资源。< / p>

返回的thing资源实例的表示形式,例如返回有关资源的哪些信息可能因用户进行身份验证而有所不同。例如,<user_x>或管理员用户可能会获得每个资源实例更丰富的数据,然后获得具有有限访问权限的用户。

对不具有thing <user_x>资源{{1}}的任何访问权限的用户进行身份验证将获得401响应。

我的问题

我想回答以下问题:

1)端点是否为RESTful?

2)端点A是否具有良好的URI设计?

3)端点B和C是RESTful吗?

4)端点B和C是否具有良好的URI设计?

我期待着你的回答。我还在下面提供了my own answers,并对此也提供反馈意见。

谢谢!

- Freddy Snijder

4 个答案:

答案 0 :(得分:8)

更新2015年3月18日13:05 CET在所提问题的评论中包含反馈意见。

<强> RESTfulness

从纯粹主义的角度来看,端点的非RESTful。例如,如果响应包含到资源的链接,则问题不会说明客户端可以检索资源而无需知道如何构造资源的URI。实际上,as pointed out in this blogpost,几乎没有在实践中定义的API,除了万维网本身之外,可以被认为是RESTful。

关于这些端点,没有什么有用的说法吗?我觉得有。 我们可以讨论处理端点的无状态和一致性,这对可伸缩性很重要。我们可以谈论对安全性很重要的端点的安全性。

对于所有端点,您可以声明以下内容:

是无国籍的吗?

是的,用户身份验证凭据是应用程序状态的一部分,并随每个请求一起发送,因此服务器需要知道处理请求而不保留状态的所有内容都在请求中。 (完整的州转移)

由于这些端点处理GET请求,它们是否具有同等效力?

端点A):是的,因为对端点A的请求(包括用户身份验证凭据)应该被视为一个整体:无论您使用相同的凭据重复相同的请求的频率如何,您将始终获得{ {1}}用于身份验证用户的资源。

但是,如果您只考虑URI,则该请求实际上不具有同等效力,因为响应会根据提供的凭据而更改。

端点B)和C):与A)类似,无论您多久重复一次,您都将始终获得URI中提供的thing thing资源。

除此之外,请求也只是在考虑URI本身时才是有意义的,您需要了解的有关请求的所有内容都在URI中,用户凭据只能更改返回的<user_x>资源的表示形式,不是返回哪些资源。

由于这些端点处理GET请求,它们是否安全?

是的,因为请求不会改变任何数据,也没有任何其他副作用。

URI设计

虽然从纯粹的REST角度来看,URI设计被认为是无关紧要的,但在实际情况下,软件开发人员和API最终用户使用和处理 URI设计是相关的

端点A是否具有良好的URI设计?

是和否。当这个URI对应用程序用户隐藏时,这不会被加入书签或共享,这样设计就可以了。但是,当此URI向最终用户公开时,此URI设计得不好,因为当将其作为链接共享时,除非她作为同一用户进行身份验证,否则收件人将看不到相同的数据。

端点B和C是否具有良好的URI设计?

是的,最终用户可以从语义上理解端点的含义,并且URI可以在用户之间共享。

因此,您可以选择仅定义端点B和C,而不是定义所有三个端点,因为它们可以提供端点A可以提供的所有内容,而且从URL中可以明显看出请求的内容。

请让我知道你的想法。谢谢!

- Freddy Snijder

答案 1 :(得分:2)

这是一个非常好的问题,也是我在为我正在开发的项目开发API时一直在问自己的问题。我是REST的新手,因此正在经历一个陡峭的学习曲线,因此远非专家!

我一直在阅读&#34; RESTful Web Services Cookbook&#34;作者:Subbu Allalaraju。

值得一提的是这些是我的想法,它们与你自己提供的答案非常相似。实际上,我确信通常情况下,身份验证凭据会影响为同一URI返回的信息。凭证实际上只是另一个查询参数。

1)端点是否为RESTful?

是的,它是无状态的,因为身份验证凭据是从客户端传递的请求。

根据https://www.w3.org/Protocols/HTTP/1.0/spec.html部分,它是幂等的10.2授权&#34;对包含授权字段的请求的响应不可缓存。&#34; 因此相同的凭据将始终检索相同的结果(验证用户的事物列表)。

2)端点A是否具有良好的URI设计?

不,它实际上与端点B或C相同,用户请求检索自己的东西,但灵活性和清晰度较低。

3)端点B和C是RESTful吗?

是的,他们是无国籍和幂等的。

4)端点B和C是否具有良好的URI设计?

是的,我认为两者都可能是有效的设计。关于每种方法的利弊都有无穷无尽的讨论!

我选择在自己的API中使用类似的东西。

GET / user / 01 /件(用户01正确验证)

回复200确定:是用户01当然您可以看到自己的东西。

GET / user / 01 / things(正确地以用户02身份验证)

响应200确定:是用户02您是超级用户,可以查看用户01具有的内容(或者可能是其中的一部分)。

GET / user / 01 / things(以03用户身份正确认证)

响应403禁止:没有用户03,即使您已经正确认证,您只是一般用户,无法看到用户01拥有的内容。或者您可以返回Response 200 OK并在响应数据中包含类似信息,这一切都取决于您如何设计API以及在这种情况下需要传递多少信息,我认为这两种方法都是有效的。

GET / user / 01 /件事(用户01身份验证不正确)

回复401未经授权:

List of HTTP status codes

答案 2 :(得分:1)

我修改了我的旧答案。我假设我们正在讨论Web文档,因此/things/1标识了一个Web文档而不是真正的文字。 (点击此处了解详情:http://en.wikipedia.org/wiki/Dereferenceable_Uniform_Resource_Identifier和此处:https://tools.ietf.org/html/rfc6920。)

  

1)Endpoint是RESTful吗?

     

2)端点A是否具有良好的URI设计?

     

3)端点B和C是否RESTful?

     

4)端点B和C是否具有良好的URI设计?

问题1和3的答案是肯定的,您可以向具有不同权限的用户发送相同资源的不同表示。 (如果要缓存这些响应,则应使用vary标头执行此操作。)

问题2和问题4的答案取决于您如何定义良好的URI设计&#34;。你的URI是完全有效的,因为REST没有任何URI结构约束,并且没有关于如何为不同的应用程序设计REST URI的标准(除了URI标准和URI模板标准),我会说它们很好。< / p>

这里有一个类似的问题:RESTful URL design: public vs private API, hierhachy API design pattern, URI vs URL design?关于这个分层与平面URI问题,如果你想阅读关于此的更详细的意见。

答案 3 :(得分:0)

首先,在HTTP中,资源的表示由标题Content-Type和Accept处理。

但客户只能建议他们喜欢的格式。服务器负责提供他想要的表示。

谈到安全性,我完全可以根据令牌的安全级别返回一个表示。

谈到您的网址,我总是更喜欢网址参数而不是查询参数(某些引擎不会使用查询参数缓存GET请求)。

但这取决于数据的结构。如果 user_id 位于的内容中,则应在URL中表示:/ things / user_id / xxxxx。

另一方面,如果user_id与资源的东西无关,请考虑删除此参数并将其添加为标题(请注意GET请求和缓存时间)。