我想知道隐式使用当前经过身份验证的用户作为API交互的上下文是否是RESTful。例如,假设我的所有API调用都使用标准HTTP安全性进行身份验证:
用于检索用户订单列表的查询是否应该是明确的?
NO:http://example.com/orders
是的:http://example.com/orders?userid=1234
当发布POST以创建新订单时,JSON是否应包含用户?
NO:{orderref:'考试/ 1',项目:{...}}
是:{用户ID:1234,orderref:'考试/ 1',项目:{...}}
无论哪种方式我都要保护,以便API只允许当前用户执行操作,但是我应该让API调用者声明每个操作的用户ID吗?
答案 0 :(得分:2)
我想说如果您可以访问许多用户的订单并且需要按用户过滤它们,那么您应该只将用户ID作为查询传递。
如果用户只能访问 他们自己的订单,则他们不必传递用户ID - 基本查询集应根据自己的身份验证详细信息对其进行限制。可能这可能不是RESTful,但不要担心 - 大多数API可能不是100%RESTful,你应该做对你的应用程序有意义而不是担心它是否RESTful - 它是一个指南,而不是一个铸铁要求。
答案 1 :(得分:0)
在任何情况下,取决于您使用的身份验证类型(BASIC或TOKEN),您必须在API调用(Headers)中发送用户信息,以便向API发出请求。
因此,当您说上下文中使用经过身份验证的用户是否有效时,当然是
示例代码
api电话
headers.Authorization = 'Bearer ' + localStorage.getItem("tokenkey");
从请求中获取用户
RequestContext.Principal.Identity.Name
答案 2 :(得分:0)
它是RESTful吗?我认为:是的。没有REST规范,所以没有什么可以说它不是。 HTTP确实允许这样做,而HTTP缓存实际上应该默认考虑对GET
请求的响应,并将Authorization
标头作为私有。
你应该使用这个设计吗?我不知道!我认为拥有每个用户端点会带来好处,因为将来它可能允许用户A检查用户B的订单。
在我们的API中,我们实际上有一个类似于您的API的示例,但我们都这样做。
/users/1234
端点。/current-user
端点。最初/current-user
端点刚刚重定向到实际当前用户的uri,但最终我们确定我们实际上只是在没有重定向的情况下返回完整对象(由于浏览器在重定向方面表现不佳) )。
current-user
端点确实还有一个self
链接,指向真实的用户资源。
总结一下。我认为你在这里很清楚,但我认为创造具有一致代表性的资源有很大的设计益处,无论谁在看它。它使事情变得更简单和更好。
如果你真的关注REST,也不要忘记你没有理由不这样做。客户应该关心的是,在某个订单列表中有一个链接,它不应该关心它的网址。
答案 3 :(得分:0)
+1马修达利的回答。特别是当经过身份验证的用户只能访问自己的订单时(我假设)。
如果经过身份验证的用户可以访问的订单列表多于他自己的订单列表,我会这样说:
/orders: the authenticated user's orders.
/orders/123: the specific user's orders.
如果123等于经过身份验证的用户的ID - 那么什么?对您的客户来说,这很可能不是问题。
通过设计REST服务,您可以考虑开发人员在使用API时的舒适度。我会说,这个是一个舒适的解决方案。
答案 4 :(得分:0)
用于检索用户订单列表的查询是否应该是明确的? NO:http://example.com/orders
是的:http://example.com/orders?userid=1234当放置POST来创建新订单时,JSON是否应包含 用户?
NO:{orderref:'考试/ 1',项目:{...}}
是:{userid:1234,orderref:' EXAM / 1',items:{...}}
如果用户只查询自己的订单,则不应在查询中明确传递用户ID - 您应该在HTTP标头中传递用户令牌,并且您的代码应该通过提供的令牌提取用户ID并确定授权用户是否拥有权限查看或修改特定数据。
如果您想让一个用户获取或修改其他用户数据,那么您可以创建其他端点 - 例如users/{userId}/orders
或users/{userId}/orders/{orderId}
。您仍然可以通过HTTP标头传递用户令牌,您的实现应检查用户是否具有此操作的管理员权限。