是否在自定义 HTTP 标头 RESTful 中传递租户?

Posted

技术标签:

【中文标题】是否在自定义 HTTP 标头 RESTful 中传递租户?【英文标题】:Is passing the tenant in a custom HTTP header RESTful? 【发布时间】:2012-10-25 22:03:21 【问题描述】:

我正在考虑在多租户环境中识别 HTTP 请求的租户的以下两种方法 - 在 URI 中硬编码租户:

/tenantUuid/foos/id

或者在自定义的HTTP Header中传递租户,如:

X-Auth-Token: 7d2f63fd-4dcc-4752-8e9b-1d08f989cc00"

(类似于:http://docs.openstack.org/api/quick-start/content/)

请注意,id 在所有租户中都是唯一的 - 因此/tenantUuid/foos/id 仍将唯一标识foo 资源。

我的问题是 - 为此使用自定义标头在理论上是否正确,或者使用自定义标头是否不安全。我也知道 X-... 标头已被弃用,但问题是忽略了这一事实。

谢谢。

【问题讨论】:

【参考方案1】:

URI 应该唯一标识资源。

但这与授权和访问是正交的。两个人可以要求相同的资源。一个人一无所获,一个省略的副本,或者一个错误;而另一个会得到整个事情,因为它们在 Authorization 标头中被正确识别。

现在 URI 可以包含租户 ID 作为其唯一 URI 的一部分,这没有任何问题。但无论哪种方式,资源本身都会(不知何故,包括通过其 URI 的组件或内部状态)“知道”它属于哪个租户。

因此,在您的情况下,您应该使用 HTTP 授权标头来正确识别请求者,然后使用该信息在内部确定特定请求的响应是否以及响应内容。请求者可能被授权查看系统上的任何租户、一个租户、部分租户或所有租户。

对于这个用例,您根本不需要自定义标题。

【讨论】:

【参考方案2】:

如果您需要租户 ID 来识别资源,那么 RESTful 方式就是将它放在 URL 中。如果你不这样做(id 在租户中是唯一的),那么从技术上讲,你不需要在 URL 或标题中使用它。

由于 id 在所有租户中都是唯一的,因此 /foos/id 可以唯一标识该资源并且是 RESTful。

我会避免使用自定义标头作为寻址资源的一种方式。它们应该用于传递辅助信息,例如接受类型、身份验证令牌等……您需要确定识别资源并将其放入 URL 是否至关重要。

【讨论】:

【参考方案3】:

对于您的应用来说,将用户与不同租户区分开来可能与像 craig 的列表这样的应用将其与城市区分开来同样有趣。

但是你想在你的 URI 中显示所有类型的分隔符吗?你想要一个像/comcast/blackeyes/long-haired/london/这样的URI吗?

RESTful 或 RESTenough 不会回答这个问题。这只是品味问题。

【讨论】:

以上是关于是否在自定义 HTTP 标头 RESTful 中传递租户?的主要内容,如果未能解决你的问题,请参考以下文章

使用 Spring Security 自定义 Http 授权标头

带有restful API GET方法的AngularJs自定义标头

Django RESTful Framework 如何从 HTTP 标头的令牌中获取用户模型?

Spring Security RememberMe & RESTful API

是否根据身份验证凭据 RESTful 返回不同的输出?

在 AFNetworking 2.x 中设置自定义标头后,RESTful API 未接收到参数