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 调用