我需要一些澄清。我一直在阅读关于REST和构建基于REST的应用程序的书籍。根据维基百科,REST本身被定义为具象状态传输。因此,我不理解所有这些无国籍的官样文章,每个人都在不停地吐出来。
从维基百科:
在任何特定的时间,客户端可以处于之间的转换
应用程序处于“静止”状态。处于休息状态的客户端可以
与用户交互,但不创建负载,也不消耗每个客户端
服务器集或网络上的存储。
他们只是说不要使用会话/应用程序级数据存储吗?
我知道REST的一个目标是使URI访问一致且可用,例如,不是在帖子中隐藏分页请求,而是使请求的页码成为get URI的一部分。对我来说很有道理。但是,说每个客户端数据(会话数据)都不应该存储在服务器端似乎有点过头了。
如果我有一个消息队列,而我的用户想要读取消息,但在读取消息时,又想在会话期间阻止某些发送者的消息通过,该怎么办?将其存储在服务器端的某个位置,并让服务器只发送未被用户阻止的消息(或消息ID),这难道不合理吗?
每次请求新的消息列表时,我真的必须发送整个消息发送者列表来阻止吗?与我相关的消息列表在一开始就不应该是公开可用的资源。
我只是想理解一下。谁来澄清一下。
更新:
我发现了一个堆栈溢出的问题,它的答案并不能让我一直走到那里:
如何在REST中管理状态
这说明客户端状态很重要,应该在每个请求上都传输....Ugg . .看起来开销很大…这样对吗??
最基本的解释是:
服务器上没有客户端会话状态。
无状态意味着服务器不在服务器端存储任何关于客户端会话的状态。
客户端会话存储在客户端上。服务器无状态意味着每个服务器可以在任何时间服务任何客户端,不存在会话关联或会话保持。相关的会话信息存储在客户机上,并根据需要传递给服务器。
这并不妨碍与web服务器通信的其他服务维护有关业务对象(如购物车)的状态,而不是有关客户端当前应用程序/会话状态的状态。
客户端的应用程序状态永远不应该存储在服务器上,而是从客户端传递到每个需要它的地方。
这就是REST中的ST(状态传输)的由来。您传递状态,而不是让服务器存储它。这是扩展到数百万并发用户的唯一方法。如果没有别的原因,只是因为数百万次会话就是数百万次会话。
会话管理的负载被分摊到所有客户机上,客户机存储它们的会话状态,服务器可以以无状态的方式为多个数量级或更多的客户机提供服务。
即使对于一个您认为只需要成千上万并发用户的服务,您仍然应该使您的服务无状态。几万还是几万,会有时间和空间成本。
无状态是HTTP协议和web一般设计的操作方式,是一个总体上更简单的实现,您有一个单一的代码路径,而不是一堆服务器端逻辑来维护一堆会话状态。
这里有一些非常基本的实现原则:
这些是原则而不是实现,你如何满足这些原则可能会有所不同。
总而言之,五个主要原则是:
给每件“东西”一个ID
把事物联系起来
使用标准方法
具有多个表示形式的资源
无状态通信
REST论文中没有任何关于身份验证或授权的内容。
因为验证RESTful请求与验证非RESTful请求并没有什么不同。身份验证与RESTful讨论无关。
解释如何为您的特定需求创建无状态应用程序,对于StackOverflow来说太宽泛了。
实现与REST相关的身份验证和授权甚至过于宽泛,一般在互联网上详细解释了各种实现方法。
寻求帮助/信息的评论将/应该被标记为
不再需要。
最基本的解释是:
服务器上没有客户端会话状态。
无状态意味着服务器不在服务器端存储任何关于客户端会话的状态。
客户端会话存储在客户端上。服务器无状态意味着每个服务器可以在任何时间服务任何客户端,不存在会话关联或会话保持。相关的会话信息存储在客户机上,并根据需要传递给服务器。
这并不妨碍与web服务器通信的其他服务维护有关业务对象(如购物车)的状态,而不是有关客户端当前应用程序/会话状态的状态。
客户端的应用程序状态永远不应该存储在服务器上,而是从客户端传递到每个需要它的地方。
这就是REST中的ST(状态传输)的由来。您传递状态,而不是让服务器存储它。这是扩展到数百万并发用户的唯一方法。如果没有别的原因,只是因为数百万次会话就是数百万次会话。
会话管理的负载被分摊到所有客户机上,客户机存储它们的会话状态,服务器可以以无状态的方式为多个数量级或更多的客户机提供服务。
即使对于一个您认为只需要成千上万并发用户的服务,您仍然应该使您的服务无状态。几万还是几万,会有时间和空间成本。
无状态是HTTP协议和web一般设计的操作方式,是一个总体上更简单的实现,您有一个单一的代码路径,而不是一堆服务器端逻辑来维护一堆会话状态。
这里有一些非常基本的实现原则:
这些是原则而不是实现,你如何满足这些原则可能会有所不同。
总而言之,五个主要原则是:
给每件“东西”一个ID
把事物联系起来
使用标准方法
具有多个表示形式的资源
无状态通信
REST论文中没有任何关于身份验证或授权的内容。
因为验证RESTful请求与验证非RESTful请求并没有什么不同。身份验证与RESTful讨论无关。
解释如何为您的特定需求创建无状态应用程序,对于StackOverflow来说太宽泛了。
实现与REST相关的身份验证和授权甚至过于宽泛,一般在互联网上详细解释了各种实现方法。
寻求帮助/信息的评论将/应该被标记为
不再需要。
我知道这里的基本问题是混淆了会议和国家。虽然REST指定不应该在服务器上存储状态,但没有什么可以阻止您存储用户会话。
管理服务器上的状态意味着您的服务器确切地知道客户机正在做什么(它们正在应用程序的哪个部分中查看哪个页面)。这是你不需要做的。
我同意其他人的说法,你应该保持会话存储的最小大小;虽然这是常识,但实际上也取决于应用程序。
因此,简而言之,您仍然可以保留一个带有缓存数据的会话,以较小的服务器负载处理请求,并通过提供一个临时身份验证/访问令牌供客户机使用来管理身份验证。每当会话/令牌过期时,生成一个新的会话/令牌,并要求客户端使用它。
有人可能会说,客户端应该更好地生成令牌。我说它是双向工作的,这取决于应用程序,以及谁将使用API。
在服务器上保留一些敏感的会话数据也是正确的做法。例如,您不能相信客户端会保留包含名为“isFreeGift”字段的购物车。这些信息应该保存在服务器上。
Santanu Dey在回答中提供的视频链接很有帮助。如果你还没看过,就看看吧。
只是一个旁注:似乎所有已经给出的答案都忽略了一个事实,即某些操作可能会导致服务器负载过重。这与功耗、硬件消耗和成本(对于按CPU周期租用的服务器)有关。一个优秀的开发人员不应该懒惰地优化他们的应用程序,即使操作可以在一些租用的服务器上的现代CPU上快速完成,而且他们不需要支付电费和维护费用。
虽然这个问题是几年前的事了,但我希望我的回答仍然会有帮助。
在开发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.