我需要一些澄清。我一直在阅读关于REST和构建基于REST的应用程序的书籍。根据维基百科,REST本身被定义为具象状态传输。因此,我不理解所有这些无国籍的官样文章,每个人都在不停地吐出来。

从维基百科:

在任何特定的时间,客户端可以处于之间的转换 应用程序处于“静止”状态。处于休息状态的客户端可以 与用户交互,但不创建负载,也不消耗每个客户端 服务器集或网络上的存储。

他们只是说不要使用会话/应用程序级数据存储吗?

我知道REST的一个目标是使URI访问一致且可用,例如,不是在帖子中隐藏分页请求,而是使请求的页码成为get URI的一部分。对我来说很有道理。但是,说每个客户端数据(会话数据)都不应该存储在服务器端似乎有点过头了。

如果我有一个消息队列,而我的用户想要读取消息,但在读取消息时,又想在会话期间阻止某些发送者的消息通过,该怎么办?将其存储在服务器端的某个位置,并让服务器只发送未被用户阻止的消息(或消息ID),这难道不合理吗?

每次请求新的消息列表时,我真的必须发送整个消息发送者列表来阻止吗?与我相关的消息列表在一开始就不应该是公开可用的资源。

我只是想理解一下。谁来澄清一下。


更新:

我发现了一个堆栈溢出的问题,它的答案并不能让我一直走到那里: 如何在REST中管理状态 这说明客户端状态很重要,应该在每个请求上都传输....Ugg . .看起来开销很大…这样对吗??


当前回答

在开发RESTful服务时,为了登录,您需要对用户进行身份验证。一种可能的选择是在每次执行用户操作时发送用户名和密码。在这种情况下,服务器将根本不存储会话数据。

Another option is to generate a session-id on the server and send it to the client, so the client will be able to send session-id to the server and authenticate with that. This is much much safer than sending username and password each time, since if somebody gets their hand on that data, then he/she can impersonate the user until the username and password is changed. You may say that even the session id can be stolen and the user will be impersonated in that case and you are right. However, in this case impersonating the user will only be possible while the session id is valid.

如果RESTful API需要用户名和密码才能更改用户名和密码,那么即使有人使用会话id冒充用户,黑客也无法锁定真正的用户。

会话id可以通过单向锁定(加密)某个标识用户的东西并将时间添加到会话id中来生成,这样就可以定义会话的过期时间。

The server may or may not store session ids. Of course, if the server stores the session id, then it would violate the criteria defined in the question. However, it is only important to make sure that the session id can be validated for the given user, which does not necessitate storing the session id. Imagine a way that you have a one-way-encryption of email, user id and some user-specific private data, like favorite color, this would be the first level and somehow adding the username date to the encrypted string and apply a two-way encryption. As a result when a session id is received, the second level could be decrypted to be able to determine which username the user claims to be and whether the session time is right. If this is valid, then the first level of encryption could be validated by doing that encryption again and checking whether it matches the string. You do not need to store session data in order to achieve that.

其他回答

Statelessness means that every HTTP request happens in complete isolation. When the client makes an HTTP request, it includes all the information necessary for the server to fulfill that request. The server never relies on information from previous requests. If that information was important, the client would have to send it again in subsequent request. Statelessness also brings new features. It’s easier to distribute a stateless application across load-balanced servers. A stateless application is also easy to cache.

实际上有两种状态。客户机上的应用程序状态和服务器上的资源状态。

web服务只需要在实际发出请求时关心应用程序的状态。其他时候,它甚至不知道你的存在。这意味着无论客户端何时发出请求,都必须包含服务器处理请求所需的所有应用程序状态。

每个客户机的资源状态都是相同的,它的适当位置在服务器上。当您将图片上传到服务器时,您创建了一个新资源:新图片有自己的URI,可以作为未来请求的目标。您可以通过HTTP协议获取、修改和删除该资源。

您完全正确,支持与服务器的完全无状态交互确实给客户机增加了额外的负担。但是,如果考虑扩展应用程序,客户机的计算能力与客户机的数量成正比。因此,扩展到大量的客户是更加可行的。

只要您让服务器负责管理与特定客户端交互相关的一些信息,这个负担就会迅速增长到消耗服务器。

这是一种权衡。

这里的无状态意味着请求的状态或元数据不在服务器端维护。通过在服务器上维护每个请求或用户的状态,将导致性能瓶颈。服务器只是被请求提供执行任何特定操作所需的属性。

对于会话管理,或者为用户提供自定义体验,需要维护一些元数据或用户状态,可能是用户的偏好,过去的请求历史。这可以通过维护cookie、隐藏属性或进入会话对象来完成。

这可以维护或跟踪用户在应用程序中的状态。

希望这能有所帮助!

The whole concept is different... You don't need to manage sessions if you are trying to implement RESTFul protocol. In that case it is better to do authentication procedure on every request (whereas there is an extra cost to it in terms of performance - hashing password would be a good example. not a big deal...). If you use sessions - how can you distribute load across multiple servers? I bet RESTFul protocol is meant to eliminate sessions whatsoever - you don't really need them... That's why it is called "stateless". Sessions are only required when you cannot store anything other than Cookie on a client side after a reqest has been made (take old, non Javascript/HTML5-supporting browser as an example). In case of "full-featured" RESTFul client it is usually safe to store base64(login:password) on a client side (in memory) until the applictation is still loaded - the application is used to access to the only host and the cookie cannot be compromised by the third party scripts...

我强烈建议禁用RESTFul服务的cookie认证…检查Basic/Digest Auth -这对于基于rest的服务应该足够了。

您必须在客户端管理客户端会话。这意味着您必须在每个请求中发送身份验证数据,并且您可能(但不一定)在服务器上有一个内存缓存,它将身份验证数据与用户信息(如身份、权限等)配对。

这种REST无状态约束非常重要。如果不应用此约束,您的服务器端应用程序将不能很好地扩展,因为维护每个客户机会话将是它的阿喀琉斯之踵。