当前位置: 首页 > 知识库问答 >
问题:

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

鲁景山
2023-03-14

我听说“RESTful API应该是无状态的。所有状态信息都应该保存在客户端”。

但当我从网页发出AJAX调用时,我注意到会话ID cookie总是被发送到服务器。使用该会话ID,我可以在服务器上获取会话对象,因此我可以“获取/设置会话中的一些状态信息”。

这是否打破了RESTful API的“无状态代码”?

(我的问题背景如下。)

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

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

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

所以,在这种情况下,我必须使用会话

详细代码在这里:这是通过RESTful调用声音的登录逻辑吗?

共有1个答案

方宁
2023-03-14

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

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

继续阅读更多细节。

传统的web应用程序使用远程会话。在这种方法中,应用程序状态完全保留在服务器上。参见罗伊·T·菲尔丁博士论文中的以下引用:

3.4.6远程会话(RS)

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

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

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

REST体系结构样式是在一组约束之上定义的,这些约束包括服务器的无状态性。根据菲尔丁的说法,REST无状态约束定义如下:

5.1.3无国籍

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

该约束会产生可见性、可靠性和可伸缩性的特性:

由于监视系统不必在单个请求数据之外查看以确定请求的全部性质,因此可见性得到了提高。可靠性得到了提高,因为它简化了从部分故障中恢复的任务。可伸缩性得到了提高,因为不必在请求之间存储状态允许服务器组件快速释放资源,并且进一步简化了实现,因为服务器不必管理跨请求的资源使用。

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

HTTP身份验证被认为是无状态的:对请求进行身份验证所需的所有信息都必须在请求中提供,而不是依赖于服务器记住以前的请求

身份验证数据应该属于标准的HTTPAuthorization头。从RFC 7235:

4.2.授权

Authorization头字段允许用户代理在收到401(未经授权)响应后,向源服务器进行身份验证。它的值由包含所请求资源领域的用户代理的身份验证信息的凭据组成。[...]

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

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

Authorization: Basic <credentials>

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

Authorization: Bearer <token>

一旦你有了会话缩写符,我猜你的应用程序中的某个地方正在创建一个超文本传输协议会话。它可以在你自己的代码中,也可以在你正在使用的框架的代码中。

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

  • HttpServletRequest#getSession()
 类似资料:
  • 我听说“RESTful API应该是无状态的,所有状态信息都应该保留在客户端”。 但是当我从web页面发出AJAX调用时,我注意到会话ID cookie总是被发送到服务器。有了那个会话ID,我就可以在服务器上获取会话对象,这样我就可以“获取/设置会话中的一些状态信息”。 这是否打破了RESTful API的“无状态代码”? (我提出问题的背景如下。) 我试图通过调用RESTful API来验证用户

  • 在TensorFlow FAQ中,它说: 在TensorFlow中,张量既有静态(推断)形状,也有动态(真实)形状。可以使用tf.Sensor读取静态形状。get_shape()方法:此形状是从用于创建张量的操作中推断出来的,可能部分完成。如果静态形状没有完全定义,可以通过计算tf.shape(t)来确定张量t的动态形状。 但我仍然不能完全理解静态形状和动态形状之间的关系。有没有例子表明他们的差异

  • 2.5 理解状态栏 状态栏是CGDB向用户显示正在输入的命令和当错误发生时报告错误的最通用的方式。CGDB不使用弹窗和其它形式的输出来告知用户信息或有错误发生。 当CGDB运行的时候,您可以通过任何在CGDB配置文件中有效的配置命令去配置CGDB。只需要代码窗口键入 : 您就可以看见一个冒号出现在状态栏中,此后输入的命令也会被显示在状态栏中。当您输入了您想要执行的命令后,键入 enter 。这将会

  • 我正在使用Python中通过纸浆的CPLEX解算器。当我解决时间限制问题时,CPLEX会将代码107打印到屏幕上,这表示“超出了时间限制,但存在整数解决方案”。但是,如果我打印我得到的是值1,根据纸浆的文档,这意味着找到了一个最佳解决方案,这实际上是错误的。 如何访问CPLEX状态代码而不是纸浆?

  • thinkphp5编写的restful风格的API,集API请求处理,权限认证,自动生成文档等功能

  • 我正在使用在Flink中执行流计算。我为我的作业定义了一个扩展的类。假设我有一个通过键控的流a,和一个流B,它被广播给所有执行程序,以使用我定义的类处理a中的元素。我知道我可以在这个类的或中注册一个计时器,这样当它超时时,我可以通过调用来删除特定密钥组的关联状态。之后我在想,这个重点群体还存在吗? 例如,在流A中,一个新消息带有,我们生成了这样的密钥组及其关联状态。之后,如果出现另一个带有的消息,