小编典典

会话真的违反了 RESTfulness 吗?

all

在 RESTful API 中使用会话真的违反了 RESTful 吗?我已经看到很多意见都朝着这两个方向发展,但我不相信会话是 RESTless
的。在我看来,我的观点是:

  • RESTful 不禁止身份验证(否则在 RESTful 服务中几乎没有用处)
  • 身份验证是通过在请求中发送身份验证令牌来完成的,通常是标头
  • 此身份验证令牌需要以某种方式获得并且可能被撤销,在这种情况下需要更新
  • 身份验证令牌需要由服务器验证(否则它不会是身份验证)

那么会话如何违反这一点呢?

  • 客户端,使用cookies实现会话
  • cookie 只是一个额外的 HTTP 标头
  • 可以随时获取和撤销会话 cookie
  • 如果需要,会话 cookie 可以有无限的生命周期
  • 会话 ID(身份验证令牌)在服务器端进行验证

因此,对于客户端而言,会话 cookie 与任何其他基于 HTTP
标头的身份验证机制完全相同,只是它使用Cookie标头而不是Authorization其他专有标头。如果没有会话附加到 cookie
值服务器端,为什么会有所不同?只要服务器 表现 RESTful,服务器端实现就不需要关心客户端。因此,cookie 本身不应使 API 成为
RESTless
,并且会话只是客户端的 cookie。

我的假设是错误的吗?是什么让会话 cookie 无 REST


阅读 98

收藏
2022-03-09

共1个答案

小编典典

首先,让我们定义一些术语:

  • RESTful:

可以将符合本节中描述的 REST 约束的应用程序描述为“RESTful”。 [15] 如果服务违反了任何必需的约束,则不能将其视为 RESTful。

根据维基百科

  • 无状态约束:

我们接下来为客户端-服务器交互添加一个约束:通信本质上必须是无状态的,如第 3.4.3 节(图 5-3)的客户端-无状态-服务器 (CSS)
样式,这样从客户端到的每个请求服务器必须包含理解请求所需的所有信息,并且不能利用服务器上存储的任何上下文。因此,会话状态完全保留在客户端上。

根据菲尔丁论文

因此,服务器端会话违反了 REST 的无状态约束,因此 RESTful 也是如此。

因此,对于客户端而言,会话 cookie 与任何其他基于 HTTP 标头的身份验证机制完全相同,只是它使用 Cookie 标头而不是
Authorization 或其他一些专有标头。

通过会话
cookie,您将客户端状态存储在服务器上,因此您的请求具有上下文。让我们尝试将负载均衡器和另一个服务实例添加到您的系统。在这种情况下,您必须在服务实例之间共享会话。很难维护和扩展这样的系统,所以它的扩展性很差......

在我看来,cookie 没有任何问题。cookie 技术是一种客户端存储机制,其中存储的数据通过每个请求自动附加到 cookie
标头。我不知道这种技术存在问题的 REST
约束。所以技术本身没有问题,问题在于它的使用。菲尔丁写了一个小节来说明他为什么认为
HTTP cookie 不好。

在我看来,我的观点是:

  • RESTful 不禁止身份验证(否则在 RESTful 服务中几乎没有用处)
  • 身份验证是通过在请求中发送身份验证令牌来完成的,通常是标头
  • 此身份验证令牌需要以某种方式获得并且可能被撤销,在这种情况下需要更新
  • 身份验证令牌需要由服务器验证(否则它不会是身份验证)

你的观点很中肯。唯一的问题是在服务器上创建身份验证令牌的概念。你不需要那部分。您需要将用户名和密码存储在客户端上,并随每个请求一起发送。除了 HTTP 基本身份验证和加密连接之外,您不需要做更多的事情:

图 1. - 受信任客户端的无状态身份验证

  • 图 1. - 受信任客户端的无状态身份验证

您可能需要在服务器端使用内存中的身份验证缓存来加快速度,因为您必须对每个请求进行身份验证。

现在,您编写的受信任的客户可以很好地工作,但是第 3 方客户呢?他们不能拥有用户名和密码以及用户的所有权限。因此,您必须单独存储特定用户可以拥有的 3rd 方客户端的权限。因此客户端开发者可以注册他们的第 3 方客户端,并获得一个唯一的 API 密钥,并且用户可以允许第 3 方客户端访问他们的部分权限。比如读取姓名和电子邮件地址,或者列出他们的朋友等等……在允许第三方客户端之后,服务器将生成一个访问令牌。第三方客户端可以使用这些访问令牌来访问用户授予的权限,如下所示:

图 2. - 第三方客户端的无状态身份验证

  • 图 2. - 第三方客户端的无状态身份验证

因此,第 3 方客户端可以从受信任的客户端(或直接从用户)获取访问令牌。之后,它可以使用 API 密钥和访问令牌发送有效请求。这是最基本的 3rd 方身份验证机制。您可以在每个 3rd 方身份验证系统(例如 OAuth)的文档中阅读有关实施细节的更多信息。当然,这可能更复杂、更安全,例如您可以在服务器端签署每个请求的详细信息,然后将签名与请求一起发送,等等......实际的解决方案取决于您的应用程序的需要。

2022-03-09