RESTful API - 如何在每个请求中包含 id/token/...?

RESTful API - how to include id/token/... in each request?

我开发了一个移动应用程序,需要访问和更新服务器上的数据。我想包括例如每个请求中的设备 ID 和一些令牌。

目前我将这些包含在 body 中,所以我只有 POST 个请求,即使是在请求从服务器读取数据时也是如此。但是,读取数据的请求应该是GET,但是我如何包含这些信息呢?我应该只在 GET 请求中添加一个 body 吗?我应该添加一些 headers 吗?如果是这样,我可以创建任意名称的自定义 headers 吗?感谢您的指导。

嗯,REST 基本上只是 browser-based 网络中已经使用多年的概念的概括。在您的应用程序中始终如一地应用这些概念,您将获得发展服务器端的自由,同时获得对客户端变化的健壮性。然而,为了从如此强大的属性中受益,需要遵循一定数量的约束,例如遵守底层传输协议的规则或依赖 HATEOAS 进一步驱动应用程序状态。与服务交互所需的任何 out-of-band 信息都会导致耦合,因此有可能破坏客户端或阻止服务器在未来发生变化。

REST 架构设计中的一个常见误解是 URI 应该是有意义的并且向客户端表达语义。然而,在 REST 架构中,URI 只是指向客户端永远不应解析的资源的指针。是否调用 URI 的决定应仅基于随附的 link 关系名称,该关系名称可能在 media-type 或通用标准中进一步描述。 IE。在可分页的 collection link 关系上,如 prevnextfirstlast 可以让客户端选择通过 collection。因此,URI 的实际结构对 REST 根本不重要。 Over-engineered URI 实际上可能进一步导致 typed resources. Therefore I don't like the term 。 non-restful-urls 看起来怎么样?

虽然通过 POST 请求发送所有内容在技术上是一个有效的选项,但它也有一些缺点需要考虑。 IANA 维护着一份您可能会使用的 HTTP methods 列表。每种方法都传达不同的承诺和语义。 IE。客户端在服务器上调用 GET 操作应该是安全的,假设调用资源不会导致任何状态更改(安全),并且在网络问题的情况下,可以重新发出请求而无需任何进一步考虑(幂等) .这些对于网络爬虫来说是非常重要的好处。除此之外,中间节点可以根据请求方法和结果响应来确定是否可以缓存响应。虽然这在客户端与服务器解耦方面不一定是个问题,但它有助于从服务器本身消除不必要的工作负载,尤其是当资源状态很少变化时,提高整个系统的可扩展性。

另一方面,

POST 不传达此类属性。在发送 POST 请求以检索数据时,客户端无法确定该请求是否真的导致资源状态发生变化。在网络问题上,请求可能已经到达服务器并且可能已经创建了一个新资源,尽管响应刚刚在中途丢失,这可能会使客户端处于不确定状态,即它是否可以简单地重新发送请求。此外,默认情况下,POST 操作的响应不可缓存,只有在明确向其添加新鲜度信息后才会缓存。 POST 方法调用请求目标资源根据资源自身的语义处理提供的表示。由于实际上任何东西都可以发送到服务器,因此服务器教导客户端请求应该是什么样子是很重要的。在 HTML 中,即这是通过 Web 表单完成的,用户可以在其中将数据填写到某些输入字段中,然后通过单击提交按钮将数据发送到服务器。同样的概念也可以应用于移动或 REST 应用程序。重用 HTML 表单或定义自己的 application/vnd.company-x.forms+json 来描述该媒体类型 public(或在 IANA 注册)可以帮助您解决这个问题。

不幸的是,关于在何处包含某些数据的实际问题过于笼统,无法给出简短的答案。它还取决于数据是否应该共享或是否具有一些与安全相关的问题。虽然参数可能通过 URL 参数(查询、矩阵、路径)传递给服务器 certain extent, it is probably not the best option in general eventhough query parameters are encrypted in SSL interactions。不过,如果 URI 应该是可粘贴的且不会丢失信息,则此选项很方便。这当然不应该包含与安全相关的数据。与安全相关的信息几乎应该总是在 HTTP header 中传递,或者至少是实际有效负载本身。

通常您应该区分内容和 meta-data 描述内容。虽然内容应该是 request/response 的实际负载,但任何描述内容的 meta-data 都应该放在 header 中。想想您要传输的图像。由于您不想弄乱图像的字节,您只需附加图像名称、压缩格式和描述如何将字节转换回 header 中的图像表示的其他属性。这种区分可能最适合标准化表示格式,因为您需要在规范的能力范围内以保证互操作性。虽然,即使在那里,事情也可能开始变得模糊。即在 EDI 领域存在一些 well-defined 标准,如 Edifact、Tradacoms 等hich 可用于交换不同的消息格式,如发票、订单、订单响应……尽管不同的 ERP 系统使用不同的俚语,这就是事情开始变得复杂和混乱的地方。

如果您可以控制您的表示格式,因为您可能没有对其进行标准化或只是含糊地定义它,但事情甚至可能更难确定是将其放在您的文档中还是通过 header 附加它秒。这完全取决于您的设计。我还看到了在有效负载中定义了自己的 header 部分的表示,因此重新创建了一个类似于 envelop-header-body 结构的 SOAP。

您的 FCM 令牌和设备 ID 实际上是请求的身份验证凭据。在 HTTP 中,您通常使用 Authorization header 和一个方案来指示服务

对于您的情况,您可以在 HTTP Authorization header 中使用不记名令牌。 虽然不记名令牌通常与 JWT 令牌一起使用,但它们不需要是那种特定格式。

您可以像 basic authentication scheme 那样连接 FCM 令牌和设备 ID。

顺便说一句,不建议在 GET 请求中使用 body,因为某些代理可能不会保留它。

关于您是否可以根据您的要求创建自定义 header 的问题。我的回答是肯定的。

如上所述,您可以使用标准 Authorization header 在每个请求中发送令牌。另一种选择是定义自定义 header。但是,您必须在服务器端实现一个逻辑来支持该自定义 header .

您可以阅读更多相关内容here