REST API:自定义 HTTP 标头与 URL 参数

Posted

技术标签:

【中文标题】REST API:自定义 HTTP 标头与 URL 参数【英文标题】:REST APIs: custom HTTP headers vs URL parameters 【发布时间】:2012-02-28 10:58:41 【问题描述】:

您何时在 REST API 的请求部分使用自定义 HTTP 标头?

例子:

你会用吗

GET /orders/view 
(custom HTTP header) CLIENT_ID: 23

而不是

GET /orders/view/client_id/23 or 
GET /orders/view/?client_id=23

【问题讨论】:

【参考方案1】:

URL 表示资源本身。 “客户端”是可以操作的资源,因此应该是基本 url 的一部分:/orders/view/client/23

参数就是这样,参数化对资源的访问。这尤其适用于帖子和搜索:/orders/find?q=blahblah&sort=foo。参数和子资源之间有一条细线:/orders/view/client/23/active versus /orders/view/client/23?show=active。我推荐搜索的子资源样式和保留参数。

由于每个端点都表示一个状态传输(以破坏助记符),因此自定义标头应仅用于不涉及资源名称(url)、资源状态(主体)的内容,或直接影响资源的参数(参数)。这留下了关于自定义标头请求的真实元数据。

HTTP 具有非常广泛的标头选择,涵盖了您需要的大部分内容。我看到自定义标头出现的地方是代表用户操作的系统到系统请求。代理系统将验证用户并将“X-User: userid”添加到标头中,并使用系统凭据访问端点。接收系统验证系统凭据是否有权代表用户执行操作,然后验证用户是否有权执行该操作。

【讨论】:

感谢您提供如此全面的答案!您是否仍将 X-User 用于移动 API,其中恶意代理(剥离标头)的风险仍然很高? 不,我提到的 X-User 的使用是在系统到系统的连接中,系统代表第三方行事。例如,用户 U 与服务器 A 对话。服务器 A 向服务器 B 提供带有 X-User 标头的凭据,以说明“使用我的凭据检查我是否有权代表用户 U 执行此操作”。这出现在面向服务的架构中,通常您使用的是 HTTPS。移动平台几乎应该始终由用户本人来执行,并使用适当的第一人称凭据进行交易。 第三段是我在 SO 上读到的信息量最大的答案之一 ;-) @Nialscorva 很好的解释!如果我希望用户通过授权容器(如我的移动应用程序)与我的 API 交互怎么办?我现在正在做的是,我的移动应用无权自行执行任何操作,最终用户也无权执行任何操作。如果用户愿意执行操作,则两个凭据都必须存在。【参考方案2】:

只有在没有其他方法通过标准或约定传递信息时,我才会使用自定义标题。 Darren102 正在解释传递该值的典型方法。通过使用使用自定义标头的典型模式,您的 Api 将更加友好。这并不是说您没有使用它们的案例,只是它们应该是最后的手段,并且 HTTP 规范尚未处理。

【讨论】:

完全同意...如果有完成任务的标准方法,请不要重新发明***。【参考方案3】:

您什么时候在 REST API 的请求部分使用...HTTP 标头?

身份验证:GUID、基本身份验证、自定义令牌等,例如, Basic Authentication with a Guid token for REST api instead of username/password

如果您参与在 PCI-DSS 或其他安全规则涵盖的域之间传递令牌或其他类似身份验证的信息,您可能还必须隐藏参数,因为某些法规明确要求身份验证元素远离可能微不足道的 URL重播(来自浏览器历史记录、代理日志等)。

【讨论】:

【参考方案4】:

自定义标头具有以下优点:

使网址不受安全因素影响(更安全,不在浏览器/代理缓存中)

就我个人而言,我只会在我自己的网络代码和我自己的网络服务器之间使用它们,以防我需要一些特殊的东西。

【讨论】:

它们也可以被代理悄悄地剥离/过滤 @fusi 好点...这里是关于它的主题:***.com/questions/20820572/…【参考方案5】:

使用 HTTP 标头 进行发送,

指令(以 JSON 格式读取输入)

元数据(提出请求的人)

在每个请求上发送的公共数据(例如身份验证, 会话)

使用路径参数制作,

对资源的特定请求 ( /country/state/city )

它们必须形成一个逻辑层次结构

使用查询参数进行发送,

对资源的操作请求(如分页、过滤器)

【讨论】:

【参考方案6】:

REST 没有标准,但可接受的方式是

GET /orders/view/23

不使用自定义标题,因此 23 after view 假定为 id,因此您将拥有一个接收 id 并因此仅生成该信息的函数。

【讨论】:

【参考方案7】:

我不会使用自定义标头,因为您不知道是否有任何代理会传递这些标头。基于 URL 是要走的路。

GET /orders/view/client/23

【讨论】:

我也不推荐自定义标头,但损坏的代理不是原因。代理坏了应该修复。【参考方案8】:

没问题:

GET /orders/view/client_id/23 or 
GET /orders/view/?client_id=23

也可以:

GET /orders/view/23 or 

我认为这也可以:

POST /orders/view 
(custom HTTP header) CLIENT_ID: 23

【讨论】:

REST-ful POST 响应应该是 HTTP 303,Location 标头设置为“/orders/view/23”。【参考方案9】:

考虑到Enveloping 不是一个好的做法,您可以使用自定义标头来包含有关部分处理的请求的更多信息。标题是secure。

【讨论】:

以上是关于REST API:自定义 HTTP 标头与 URL 参数的主要内容,如果未能解决你的问题,请参考以下文章

如何访问 Django Rest Framework 上的自定义 HTTP 请求标头?

Spring Boot REST API 版本控制的自定义标头方法

Alamofire - 带有自定义标头的 Rest API 调用

Django-Rest-Framework 系统检查自定义 HTTP 标头(应用程序 - 令牌)

如何在反应JavaScript中获取自定义标头?

Angular 2 Http 删除与 Web API REST 一起使用的标头