我听说“RESTful API应该是无状态的,所有状态信息都应该保留在客户端”。
但是当我从web页面发出AJAX调用时,我注意到会话ID cookie总是被发送到服务器。有了那个会话ID,我就可以在服务器上获取会话对象,这样我就可以“获取/设置会话中的一些状态信息”。
这是否打破了RESTful API的“无状态代码”?
(我提出问题的背景如下。)
我试图通过调用RESTful API来验证用户名和密码来实现一个登录页面。
每次用户尝试访问我的站点的页面时,登录servlet过滤器
将检查该用户的session
(这是调用getsession()
的地方),以查看是否存在有效的登录信息。如果不是,登录筛选器会将用户重定向到登录页面。
在登录页面上,使用用户名和密码对服务器上的RESTful API进行AJAX调用。根据RESTful API调用的结果,页面上的JavaScript将决定是否允许用户进入我的站点。
因此,在这个场景中,我不得不使用session
。
详细的代码位于这里:这是通过RESTful调用声音登录逻辑吗?
简单地说:在REST应用程序中,每个请求必须包含服务器理解的所有必要信息,而不是依赖于服务器记住先前的请求。
在服务器上存储会话状态违反了REST体系结构的无状态约束。因此会话状态必须完全由客户端处理。
继续阅读以了解更多细节。
传统的web应用程序使用远程会话。在这种方法中,应用程序状态完全保留在服务器上。参见以下引用罗伊·T·菲尔丁的论文:
3.4.6远程会话(RS)
远程会话样式是客户机-服务器的一种变体,它试图将客户机组件(而不是服务器组件)的复杂性最小化或重用最大化。每个客户端在服务器上发起一个会话,然后调用服务器上的一系列服务,最后退出会话。应用程序状态完全保留在服务器上。[...]
远程会话样式的优点是,在服务器上集中维护接口更容易,在功能扩展时减少了对部署的客户端不一致性的担忧,并且如果交互使用服务器上的扩展会话上下文,则提高了效率。缺点是,由于存储的应用程序状态,它降低了服务器的可伸缩性,并且降低了交互的可见性,因为监视器必须知道服务器的完整状态。
REST体系结构样式定义在一组约束的顶部,这些约束包括服务器的无状态性。根据Fielding,REST无状态约束定义如下:
5.1.3无国籍
[...]从客户端到服务器的每个请求必须包含理解请求所必需的所有信息,并且不能利用服务器上存储的任何上下文。因此,会话状态完全保留在客户端上。[...]
这种约束导致了可见性、可靠性和可伸缩性的特性:
由于监视系统不必查看单个请求数据之外的内容来确定请求的全部性质,因此提高了可见性。可靠性得到了提高,因为它简化了从部分故障中恢复的任务。可伸缩性得到了改善,因为不必在请求之间存储状态允许服务器组件快速释放资源,并且进一步简化了实现,因为服务器不必管理跨请求的资源使用。
如果客户端请求需要身份验证的受保护资源,则每个请求都必须包含所有必要的数据,以便进行正确的身份验证/授权。请参阅RFC7235中的引用:
HTTP身份验证被认为是无状态的:身份验证请求所必需的所有信息都必须在请求中提供,而不是依赖于服务器记住先前的请求。
和身份验证数据应属于标准的HTTPauthorization
头。RFC 7235中:
4.2.授权
此HTTP标头的名称很不幸,因为它携带身份验证而不是授权数据。
对于身份验证,您可以使用基本HTTP身份验证方案,该方案以用户名和密码对的形式传输凭据,使用Base64:
Authorization: Basic <credentials>
如果您不想在每个请求中发送用户名和密码,则可以将用户名和密码交换为每个请求中发送的令牌(如JWT)。JWT可以包含用户名、过期日期和可能与应用程序相关的任何其他元数据:
Authorization: Bearer <token>
在Java应用程序中,必须确保没有调用以下方法:
HttpServletRequest#GetSession()
HttpServletRequest#GetSession(boolean)
带有true
我听说“RESTful API应该是无状态的。所有状态信息都应该保存在客户端”。 但当我从网页发出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中,一个新消息带有,我们生成了这样的密钥组及其关联状态。之后,如果出现另一个带有的消息,