如何理解“RESTful API是无状态的”?

时间:2015-12-07 09:16:16

标签: rest

我听说RESTful API should be stateless. All state info should be kept on client side

但是当我从网页发出ajax调用时,我注意到会话ID cookie总是被发送到服务器。使用该会话ID,我可以在服务器上获取会话对象。因此我可以get/set some state info in the session

这会破坏RESTful API的code of being stateless吗?

ADD 1

(我的问题背景如下。)

我尝试通过调用RESTful API来验证用户名和密码来实现登录页面。

每次用户尝试访问我的网站页面时,登录servlet filter都会检查session(这是getSession()被调用的地方),以便该用户查看是否有效登录信息存在。如果没有,登录过滤器会将用户重定向到登录页面。

在登录页面上,使用用户名和密码对服务器上的RESTful API进行ajax调用。根据RESTful API的返回结果,页面上的JavaScript将决定是否让用户进入我的网站。

因此,在这种情况下,我必须使用session

详细代码位于: Is this login logic via RESTful call sound?

1 个答案:

答案 0 :(得分:69)

简单地说:在REST应用程序中,每个请求必须包含服务器必须理解的所有信息,而不是依赖于服务器记住先前的请求。

在服务器上存储会话状态违反了REST体系结构的无状态约束。因此,会话状态必须完全由客户端处理。

继续阅读以了解更多详情。

会话状态

传统的网络应用程序使用远程会话。在此方法中,应用程序状态完全保留在服务器上。请参阅Roy T. Fielding的dissertation

中的以下引用
  

3.4.6 Remote Session (RS)

     

远程会话样式是客户端 - 服务器的变体,它试图最小化客户端组件而不是服务器组件的复杂性或最大化重用。每个客户端在服务器上启动会话,然后在服务器上调用一系列服务,最后退出会话。应用程序状态完全保留在服务器上。 [...]

虽然这种方法带来了一些优势,但它降低了服务器的可扩展性:

  

远程会话风格的优点是更容易在服务器上集中维护接口,减少了在扩展功能时对已部署客户端中的不一致性的担忧,并且如果交互使用扩展会话上下文,则可提高效率服务器。缺点是由于存储的应用程序状态,它降低了服务器的可伸缩性,并降低了交互的可见性,因为监视器必须知道服务器的完整状态。

无状态约束

REST架构样式是在包含服务器无状态的集合约束的顶部定义的。根据Fielding的说法,REST 无状态约束定义如下:

  

5.1.3 Stateless

     

[...]从客户端到服务器的每个请求必须包含理解请求所需的所有信息,并且不能利用服务器上任何存储的上下文。因此,会话状态完全保留在客户端上。 [...]

此约束会导致可见性可靠性可伸缩性的属性:

  

可见性得到改善,因为监控系统不必超出单个请求数据,以确定请求的完整性质。可靠性得到改善,因为它简化了从部分故障中恢复的任务。可扩展性得到改善,因为不必在请求之间存储状态允许服务器组件快速释放资源,并进一步简化实现,因为服务器不必跨请求管理资源使用。

身份验证和授权

如果客户端请求需要身份验证的受保护资源,则每个请求都必须包含所有必要的数据才能进行正确身份验证/授权。请参阅RFC 7235

中的这句话
  

HTTP认证被认为是无状态的:认证请求所需的所有信息必须在请求中提供,而不是依赖于服务器记住先前的请求。

身份验证数据应属于标准HTTP Authorization标头。来自RFC 7235

  

4.2. Authorization

     

Authorization标头字段允许用户代理使用原始服务器对自身进行身份验证 - 通常(但不一定)在收到401(未授权)响应后。其值由包含所请求资源领域的用户代理的认证信息的凭证组成。 [...]

此HTTP标头的名称很不幸,因为它带有身份验证而不是授权数据。

对于身份验证,您可以使用Basic HTTP Authentication方案,该方案将凭据作为用户名和密码对进行传输,使用Base64进行编码:

Authorization: Basic <credentials>

如果您不想在每个请求中发送用户名和密码,则可以将用户名和密码交换为在每个请求中发送的令牌(例如JWT)。 JWT可以包含用户名,到期日期以及可能与您的应用程序相关的任何其他元数据:

Authorization: Bearer <token>

您的服务器可能出现什么问题

一旦你有一个会话标识符,我想你的应用程序中正在创建一个某处的HTTP会话。它可以位于自己的代码或您正在使用的代码中。

在Java应用程序中,您必须确保以下方法被调用: