如何理解“RESTful API 是无状态的"? [英] How to understand "RESTful API is stateless"?

查看:92
本文介绍了如何理解“RESTful API 是无状态的"?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

But when I issue an AJAX call from a web page, I noticed that a session ID cookie is always sent along to the server. With that session ID, I can obtain the session object on the server, and thus I can "get/set some state info in the session".

这是否打破了无国籍守则"?对于 RESTful API?

Does this break the "code of being stateless" for a RESTful API?

(我的问题的背景如下.)

(The background of my question is as below.)

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

I tried to implement a login page by calling a RESTful API to validate a username and a password.

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

Each time a user attempts to visit a page of my site, a login servlet filter will check the session (this is where getSession() gets called) for that user to see if valid login info exists. If not, the login filter will redirect the user to the login page.

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

On the login page, an AJAX call is made to a RESTful API on the server with the username and the password. Depending on the result of that RESTful API call, the JavaScript on the page will decide whether to let the user into my site.

所以,在这种情况下,我不得不使用 session.

So, in this scenario, I kind of have to use session.

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

推荐答案

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

Simply put: In REST applications, each request must contain all of the information necessary to be understood by the server, rather than be dependent on the server remembering prior requests.

在服务器上存储会话状态违反了 REST 架构的无状态约束.所以会话状态必须完全由客户端处理.

Storing session state on the server violates the stateless constraint of the REST architecture. So the session state must be handled entirely by the client.

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

Keep reading for more details.

传统网络应用程序使用远程会话.在这种方法中,应用程序状态完全保存在服务器上.请参阅 Roy T. Fielding 的论文中的以下引述:

Traditional web applications use remote sessions. In this approach, the application state is kept entirely on the server. See the following quote from Roy T. Fielding's dissertation:

3.4.6 远程会话 (RS)

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

The remote session style is a variant of client-server that attempts to minimize the complexity, or maximize the reuse, of the client components rather than the server component. Each client initiates a session on the server and then invokes a series of services on the server, finally exiting the session. Application state is kept entirely on the server. [...]

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

While this approach introduces some advantages, it reduces the scalability of the server:

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

The advantages of the remote session style are that it is easier to centrally maintain the interface at the server, reducing concerns about inconsistencies in deployed clients when functionality is extended, and improves efficiency if the interactions make use of extended session context on the server. The disadvantages are that it reduces scalability of the server, due to the stored application state, and reduces visibility of interactions, since a monitor would have to know the complete state of the server.

无状态约束

REST 架构风格定义在一组约束之上,包括服务器无状态.根据 Fielding 的说法,REST 无状态约束定义如下:

The stateless constraint

The REST architectural style is defined on the top of a set constraints that include statelessness of the server. According Fielding, the REST stateless constraint is defined as the following:

5.1.3 无状态

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

[...] each request from client to server must contain all of the information necessary to understand the request, and cannot take advantage of any stored context on the server. Session state is therefore kept entirely on the client. [...]

这个约束导致了可见性可靠性可扩展性的属性:

This constraint induces the properties of visibility, reliability, and scalability:

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

Visibility is improved because a monitoring system does not have to look beyond a single request datum in order to determine the full nature of the request. Reliability is improved because it eases the task of recovering from partial failures. Scalability is improved because not having to store state between requests allows the server component to quickly free resources, and further simplifies implementation because the server doesn't have to manage resource usage across requests.

身份验证和授权

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

Authentication and authorization

If the client requests protected resources that require authentication, every request must contain all necessary data to be properly authenticated/authorized. See this quote from the RFC 7235:

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

HTTP authentication is presumed to be stateless: all of the information necessary to authenticate a request MUST be provided in the request, rather than be dependent on the server remembering prior requests.

并且认证数据应该属于标准的 HTTP Authorization 标题.来自 RFC 7235:

And authentication data should belong to the standard HTTP Authorization header. From the RFC 7235:

4.2.授权

Authorization 标头字段允许用户代理向源服务器验证自己的身份——通常但不一定是在收到 401(未授权)响应后.它的值由包含所请求资源领域的用户代理的身份验证信息的凭据组成.[...]

The Authorization header field allows a user agent to authenticate itself with an origin server -- usually, but not necessarily, after receiving a 401 (Unauthorized) response. Its value consists of credentials containing the authentication information of the user agent for the realm of the resource being requested. [...]

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

The name of this HTTP header is unfortunate because it carries authentication instead of authorization data.

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

For authentication, you could use the Basic HTTP Authentication scheme, which transmits credentials as username and password pairs, encoded using Base64:

Authorization: Basic <credentials>

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

If you don't want to send the username and password in each request, the username and password could be exchanged for a token (such as JWT) that is sent in each request. JWT can contain the username, an expiration date and any other metadata that may be relevant for your application:

Authorization: Bearer <token>

您的服务器可能有什么问题

一旦你有了一个会话标识符,我想一个 HTTP 会话正在你的应用程序中某处被创建.它可以在您自己的代码中,也可以在您正在使用的框架的代码中.

What might be wrong with your server

Once you have a session indentifier, I guess a HTTP session is being created somewhere in your application. It can be in your own code or in the code of the framework you are using.

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

In Java applications, you must ensure that the following methods are not getting invoked:

这篇关于如何理解“RESTful API 是无状态的"?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆