如果REST应用程序应该是无状态的,那么如何管理会话?


536

我需要一些澄清。我一直在阅读有关REST和构建RESTful应用程序的信息。根据维基百科,REST本身被定义为“ 代表性状态转移”。因此,我不理解每个人不断涌出的所有无状态gobbledeygook

从维基百科:

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

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

我知道REST的一个目标是使URI访问保持一致和可用,例如,而不是在帖子内部隐藏分页请求,而使请求的页码成为GET URI的一部分。我感觉合理。但是,似乎没有任何理由说每个客户端数据(会话数据)都不应存储在服务器端。

如果我有一条消息队列,并且我的用户想阅读消息,但是在阅读过程中,他想在会话期间阻止某些发件人消息通过,该怎么办?将其存储在服务器端的某个位置,让服务器仅发送未被用户阻止的消息(或消息ID),这是否有意义?

每次我请求新的消息列表时,是否真的必须发送整个消息发件人列表才能阻止?首先,与我相关的消息列表甚至不会/也不应该是公共可用的资源。

同样,只是试图理解这一点。有人澄清。


更新:

我发现了一个堆栈溢出问题,该问题的答案并不能完全解决我的问题: 如何在REST管理状态,该状态表示重要的客户端状态在每个请求上全部转移。 ..似乎有很多开销...是这样吗?


2
@ S.Lott:我认为这不是故意的误导。由于术语混乱,我认为这是一种误解。
只是我的正确观点2010年

2
@正确的观点:有趣的猜测。我本人不敢相信这样的事情,因为从“无状态”显而易见,这意味着REST协议本身是无状态的。这并没有说明底层应用程序状态,而是使用PUT,POST和DELETE请求对其进行更新。
S.Lott

@ S.Lott:HTTP协议本身是无状态的。从下面的讨论中,REST是如何在不让Web服务器处理会话状态(与DB等其他状态相反)的情况下构建应用的观点。我什至不认为REST 一种协议,而是关于如何使用HTTP协议的观点。我你们已经弄清楚了,这是关于如何通过让客户端存储所有特定于客户端的会话数据,并使URI访问尽可能幂等来构建可伸缩应用程序的方法,除非不应这样做。也许不是... :(
扎克2010年

1
“也许不是。”那是什么意思?您有新问题吗?随时搜索SO。如果这里不存在,请询问。
S.Lott

有没有人读过Webber,Parastatidis和Robinson的ReST实践(或者看过他们的restbucks示例)?下面的答案很有意义,但是restbucks示例中的咖啡订单肯定是关于客户的状态吗?订单数量与客户数量成比例。客户端状态和资源之间的界线在哪里?
Rikki 2015年

Answers:


339

无状态意味着每个HTTP请求都是完全隔离的。客户端发出HTTP请求时,它包含服务器完成该请求所需的所有信息。服务器从不依赖先前请求中的信息。如果该信息很重要,则客户端将不得不在后续请求中再次发送该信息。无状态也带来了新功能。在负载平衡的服务器之间分发无状态应用程序更加容易。无状态应用程序也易于缓存。

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

当您实际发出请求时,Web服务仅需要关心您的应用程序状态。剩下的时间,它甚至都不知道您的存在。这意味着,每当客户端发出请求时,它都必须包括服务器需要处理的所有应用程序状态。

每个客户端的资源状态都相同,并且它在服务器上的适当位置。当您将图片上传到服务器时,您将创建一个新资源:新图片具有其自己的URI,并且可以成为将来请求的目标。您可以通过HTTP获取,修改和删除此资源。

希望这有助于区分无状态和各种状态的含义。


4
这是否意味着每次发送请求时,客户端都应该发送其用户/密码进行身份验证?因为我想存储一个会话,即使该会话位于所有服务器之间共享的no-sql db上,也不是无状态的吗?
卡洛斯·纳瓦罗·阿斯蒂亚萨兰

1
@CarlosNavarroAstiasarán有多种处理无状态身份验证的技术。以Google JWT为例。
geoidesic '18

1
@geoidesic:“因为JSON Web令牌是无状态的,所以不存储服务器状态就无法使它们无效,从而失去了无状态令牌的优势。” WIkipedia
ulatekh

@ulatekh这是对代币可以做什么的严重歪曲。将批准的ID与令牌一起存储,并且仅接受具有批准的ID的令牌作为声明是非常简单的。无状态并不意味着您无法在数据库中进行任何操作。本质上,您在数据库中存储的ID必须与令牌中的相同ID匹配。要撤消令牌,可以从数据库中删除ID。服务本身不会记住任何状态。甚至更好的是,将签名密钥与用户一起存储在数据库中,然后撤销密钥。
Andrew T Finnell

@AndrewTFinnell:如果必须将批准的ID存储在服务器上,则必须将其存储在可以处理REST登录的所有潜在服务器上,这可能涉及大规模并行Web服务器体系结构中的许多服务器状态。
ulatekh '19

491

基本解释是:

服务器上没有客户端会话状态。

无状态意味着服务器服务器端不存储有关客户端会话的任何状态。

客户端会话存储在客户端上。服务器是无状态的,这意味着每个服务器都可以随时为任何客户端提供服务,没有会话亲缘关系粘性会话。相关的会话信息存储在客户端上,并根据需要传递到服务器。

但这并不排除Web服务器与之交谈的其他服务维持有关业务对象(例如购物车)的状态,而不是维持客户端当前的应用程序/会话状态。

客户端的应用程序状态不应该被存储在服务器上,但是从绕过客户端的每一个需要它的地方。

这就是REST中的ST的来源,即State Transfer。您转移状态而不是让服务器存储状态。这是扩展到数百万并发用户的唯一方法。如果不是因为无数个原因,就是因为数百万个会话就是数百万个会话。

会话管理的负载在所有客户端上分摊,客户端存储其会话状态,并且服务器可以无状态方式服务于多个数量级或更多的客户端。

即使对于您认为需要数千个并发用户的服务,您仍应使服务成为无状态。数以万计的仍然是数以万计的,并且会伴随着时间和空间成本。

HTTP协议和Web的总体设计是无状态的,它是整体上更简单的实现,并且您只有一个代码路径,而不是一堆服务器端逻辑来维护一堆会话状态。

有一些非常基本的实现原则:

这些是原则而非实现,您如何满足这些原则可能会有所不同。

总之,五项关键原则是:

  1. 给每个“东西”一个ID
  2. 将事物链接在一起
  3. 使用标准方法
  4. 具有多种表示形式的资源
  5. 无状态沟通

REST 论文中没有关于身份验证或授权的任何内容。

因为从没有身份验证的请求到对RESTful的请求进行身份验证没有什么不同。身份验证与RESTful讨论无关。

对于StackOverflow而言,解释如何为您的特定要求创建无状态应用程序的方法太过广泛了。

与REST相关的实施身份验证和授权的方法过于广泛,通常在Internet上详细解释了各种实现方法。

寻求帮助/信息的评论将/应该被标记为 不再需要


22
这似乎是一个非常大胆的声明,它是扩展到数百万用户的唯一方法。为什么服务器端会话不能只是另一项服务?
扎克2010年

27
@Zak:因为数百万个会话就是数百万个会话。关键是要避免所有此会话管理的开销。
S.Lott

91
这不是大胆的经验

21
我的回答中没有任何内容表示基于每个请求的数据库访问的解决方案,如果您认为这样做的话,那么您就无法理解这种规模的身份验证和授权。身份验证可以隐含在状态中,您是否认为facebook对其REST API的每个请求都进行“数据库访问”?还是Google呢?提示:否

6
因此,如果我将用户状态存储在分布式缓存中,例如说memcache,而我的所有Web服务器现在都不需要存储任何状态,而是从memcache中获取状态,那么我可以认为该应用程序是无状态的吗?
Jaskey 2014年

76

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

不。他们不是在说些小话。

他们说的不是定义“会话”。不要登入 不要注销。在请求中提供凭据。每个请求都是独立的。

您仍然有数据存储。您仍然具有身份验证和授权。您只是不浪费时间建立会话和维护会话状态。

关键是每个请求(a)完全独立,并且(b)可以琐碎地移植到大型并行服务器场中,而无需任何实际工作。Apache或Squid可以盲目且成功地传递RESTful请求。

如果我有一条消息队列,并且我的用户想阅读消息,但是在阅读过程中,他想在会话期间阻止某些发件人消息通过,该怎么办?

如果用户需要过滤器,则只需在每个请求上提供过滤器。

...让服务器仅发送未被用户阻止的消息(或消息ID)是否合理?

是。在RESTful URI请求中提供过滤器。

每次我请求新的消息列表时,是否真的必须发送整个消息发件人列表才能阻止?

是。这个“要阻止的消息发件人列表”可以有多大?PK的简短列表?

GET请求可能非常大。如有必要,即使听起来像是一种查询,也可以尝试POST请求。


28
“不登录。不注销。在请求中提供凭据。” 我总是在这样的问题中看到这样的回答:如何在REST API中保持无状态,而又没有关于在客户端上何处/如何存储这些凭据的任何详细信息。当然,我们不应该将用户名和密码存储在本地存储中!
BeniRose

2
@BeniRose我们不能在本地存储中存储令牌,而不能在将唯一标识用户的请求中使用该令牌吗?
Nikhil Sahu

1
据我了解,本地存储存在很多安全问题。但也有一堆与客户端的会话的其他问题,如无效的令牌,将用户登录了,等等
BeniRose

3
您使用具有签名的JWT,签名验证很快,因此您可以检查该状态的有效性。
Archimedes Trajano '18年

36

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

一旦您在服务器上承担了一点点责任来管理与特定客户端的交互相关的某些信息,该负担就会迅速增加,以消耗服务器。

这是一个权衡。


32

用户应用程序状态管理的历史视图

传统意义上的会话将用户的状态保留在服务器内部的应用程序中。这可能是流中的当前页面,也可能是先前输入的页面,但尚未持久保存到主数据库中。

产生这种需求的原因是客户端缺乏有效的维护状态的标准,而没有制作特定于客户端(即特定于浏览器)的应用程序或插件。

随着时间的推移,HTML5和XML标头请求已经标准化了在客户端(即浏览器)侧以标准方式存储包括应用程序状态在内的复杂数据的概念,而无需在服务器之间来回移动。

REST服务的一般用法

通常在需要执行事务或需要检索数据时调用REST服务。

REST服务应由客户端应用程序而不是最终用户直接调用。

验证中

对于对服务器的任何请求,请求的一部分应包含授权令牌。它的实现方式是特定于应用程序的,但通常是a BASICCERTIFICATE身份验证身份验证形式。

REST服务不使用基于表单的身份验证。但是,如上所述,REST服务不是要由用户调用,而是由应用程序调用。应用程序需要管理获取身份验证令牌。以我为例,我使用了带有OAuth 2.0JASPIC的 cookie 来连接到Google进行身份验证,并使用简单的HTTP身份验证进行自动化测试。我也通过JASPIC使用HTTP标头身份验证进行本地测试(尽管可以在SiteMinder中执行相同的方法)

根据这些示例,身份验证是在客户端进行管理的(尽管SiteMinder或Google会将身份验证会话存储在客户端),但是对于该状态无法做任何事情,但是它不是REST服务应用程序的一部分。

检索请求

REST中的检索请求GET是请求特定资源并且可缓存的操作。不需要服务器会话,因为请求具有检索数据所需的一切:身份验证和URI。

交易脚本

如上所述,客户端应用程序本身会调用REST服务以及它在客户端管理的身份验证。

这对于REST服务(如果正确完成)意味着向REST服务器发出单个请求将包含执行单个事务中所需的所有操作的单个用户操作所需的所有内容,即事务脚本就是这种模式叫做。

POST通常,这是通过请求完成的,但PUT也可以使用其他请求。

许多人为的REST示例(我自己就是这样做的)试图遵循HTTP协议中定义的内容,在经历了此之后,我决定更加实用,将其留给GET和POST。该POST方法甚至不必实现POST-REDIRECT-GET模式。

但是无论如何,如上所述,客户端应用程序将是调用该服务的应用程序,并且仅POST在需要时(并非每次)都调用带有所有数据的请求。这样可以防止对服务器的持续请求。

轮询

尽管REST也可以用于轮询,但是除非浏览器具有兼容性,否则我不建议您使用它,除非您必须使用它。为此,我将使用我为其设计了API合约的 WebSockets 。较旧的浏览器的另一种选择是CometD。


27

REST非常抽象。拥有一些很好的,简单的,真实的示例会有所帮助。

以所有主要的社交媒体应用为例-Tumblr,Instagram,Facebook和Twitter。它们都具有永久滚动的视图,您向下滚动的距离越远,看到的内容越多,时光倒流的时间越远。但是,我们都经历过那一刻,您失去了滚动到的位置,应用程序将您重新设置为顶部。就像您退出该应用程序一样,那么当您重新打开它时,您又回到了顶部。

之所以这样,是因为服务器未存储您的会话状态。可悲的是,您的滚动位置只是存储在客户端的RAM中。

幸运的是,当您重新连接时,您不必重新登录,但这仅是因为您客户端存储的登录证书尚未过期。删除并重新安装该应用程序,您将不得不重新登录,因为服务器未将您的IP地址与您的会话相关联。

您在服务器上没有登录会话,因为它们遵守REST。


现在,以上示例完全不涉及Web浏览器,但是在后端,这些应用程序通过HTTPS与主机服务器进行通信。我的观点是,REST不必涉及cookie和浏览器等。有多种存储客户端会话状态的方法。

但是,让我们再谈一谈网络浏览器,因为这带来了REST的另一个主要优势,这里没有人在谈论。

如果服务器尝试存储会话状态,应该如何识别每个单独的客户端?

它不能使用其IP地址,因为许多人可能在共享路由器上使用相同的地址。那怎么办呢?

它不能使用MAC地址有很多原因,其中最重要的原因是您可以同时在不同的浏览器和应用程序上登录多个不同的Facebook帐户。一个浏览器很容易伪装成另一个浏览器,并且MAC地址也很容易被欺骗。

如果服务器必须存储某些客户端状态以识别您的身份,则它必须将其存储在RAM中的时间长于处理您的请求所需的时间,否则它必须缓存该数据。服务器的RAM和缓存数量有限,更不用说处理器速度了。服务器端状态以指数形式添加到所有这三个状态。另外,如果服务器要存储有关会话的任何状态,则它必须针对当前登录的每个浏览器和应用程序以及所使用的每个不同设备分别存储该状态。


所以...我希望您现在明白为什么REST对于可伸缩性如此重要。我希望您能开始理解为什么服务器端会话状态对服务器可扩展性的影响为何焊接砧对汽车加速的影响。


人们感到困惑的地方是认为“状态”是指存储在数据库中的信息。不,它指的是使用时需要在服务器RAM中存储的所有信息。


13

我看到这里的基本问题是将SessionState混合在一起。尽管REST指定您不应该将状态存储在服务器上,但是没有什么可以阻止您存储用户Session

在服务器上管理状态意味着您的服务器确切地知道客户端在做什么(他们正在应用程序的哪个部分中查看哪个页面)。这是您不需要做的。

我同意其他人的意见,即您应将会话存储空间保持在最小大小。尽管这是常识,但实际上也取决于应用程序。因此,简而言之,您仍然可以与缓存的数据保持会话,以减轻服务器的负载来处理请求,并通过提供临时的身份验证/访问令牌供客户端使用来管理身份验证。只要会话/令牌过期,就生成一个新的会话/令牌,并要求客户端使用它。

可能有人认为客户应该更好地生成令牌。我说这是双向的,这取决于应用程序以及谁将使用该API。

同样,在服务器上保留一些敏感的会话数据也应该是正确的方法。您不能信任客户保留其购物车(例如)包含名为“ isFreeGift”的字段。此类信息应保留在服务器上。

Santanu Dey在回答中提供的视频链接很有帮助。如果没有,请观看。

附带说明:似乎已经给出的所有答案似乎都忽略了某些操作可能导致服务器负担沉重的事实。这与功耗,硬件消耗和成本(对于按CPU周期租用的服务器)有关。一个好的开发人员不应该懒惰地优化他们的应用程序,即使该操作可以非常快地在某些租用服务器上的现代CPU上完成,而无需为其支付电费和维护费。

尽管这个问题已有几年历史,但我希望我的回答仍然会有所帮助。


4
我通常都同意这种观点,但是最近有一种趋势声称,即使会话标识符也不应存储在服务器上。我还没有找出替代的解决方案是什么,智威汤逊很好吹捧,但带有陷阱的屈指可数:cryto.net/~joepie91/blog/2016/06/19/...
BeniRose

11

无状态意味着服务状态不会在后续请求和响应之间持续存在。每个请求都带有其自己的用户凭据,并分别进行了身份验证。但是在有状态时,可以从任何先前的请求中得知每个请求。所有有状态请求都是面向会话的,即每个请求都需要了解并保留先前请求中所做的更改。

银行应用程序是有状态应用程序的一个示例。用户首先登录然后进行交易并注销的位置。如果注销后用户尝试进行交易,那么他将无法进行交易。

是的,http协议本质上是无状态的协议,但是为了使其具有状态,我们使用HTTP cookie。因此,默认情况下是SOAP。但这同样可以使之成为有状态的,取决于您使用的框架。

HTTP是无状态的,但仍然可以通过使用不同的会话跟踪机制在Java应用程序中维护会话。

是的,我们还可以在Web服务中维护会话,无论是REST还是SOAP。可以使用任何第三方库来实现,也可以由我们自己实现。

取自http://gopaldas.org/webservices/soap/webservice-is-stateful-or-stateless-rest-soap


11

没有勺子。

不要将无状态视为“ 一次又一次将所有内容发送到服务器”。没门。总会有状态-数据库本身毕竟一种状态,您是注册用户,因此没有服务器端,任何一组客户端信息都将无效。从技术上讲,您永远不会真正处于无国籍状态。

每次辩论都在登录上说一句话

不保留会话并每次登录都不意味着什么?有些意思是“每次发送密码”,这简直是愚蠢的。有人说“当然不行,而是发送令牌 ”-瞧,PHP会话几乎就是这样做的。它会发送一个会话ID,这是一种令牌,它可以帮助您找到自己的个人资料,而不必每次都重新发送u / pw。它也相当可靠且经过了良好的测试。是的,很方便,这可能会带来缺点,请参阅下一段。

减少占地面积

相反,您应该做的事以及真正有意义的事,是将Web服务器的占用空间减至最少。像PHP这样的语言使将所有内容填充到会话存储中变得非常容易-但是会话具有价格标签。如果您有多个Web服务器,则它们需要共享会话信息,因为它们也共享负载-它们中的任何一个都可能必须处理下一个请求。

共享存储是必须的。服务器至少需要知道某人是否已登录。(而且,如果您每次都要决定数据库时都在打扰数据库,那么您几乎注定要失败。)共享存储需要比数据库快很多。这带来了诱惑:好的,我的存储空间非常快,为什么不在那里存储所有内容?-这就是相反的情况。

所以您说的是,将会话存储空间降到最低?

再次,这是您的决定。出于性能原因,您可以在此处存储内容(数据库几乎总是比Redis慢),可以冗余地存储信息,实现自己的缓存,无论如何-请记住,如果您存储大量垃圾,Web服务器将具有更大的负载在他们。而且,如果它们在重负荷下破裂(并且会破裂),您将丢失有价值的信息;使用REST的思维方式,在这种情况下发生的所有事情就是客户端再次发送相同的(!)请求,并且这次得到服务。

那怎么办呢?

这里没有万能的解决方案。我会说选择无国籍水平,然后再去做。会议可能会受到某些人的喜爱而受到其他人的讨厌,但它们没有任何进展。对于每个请求,发送尽可能多的信息,也许更多;但不要将无状态视为没有会话,也不能解释为每次都在登录。服务器必须以某种方式知道是你自己;PHP会话ID是一种好方法,手动生成的令牌是另一种方法。

思考和决定,不要让设计趋势为您考虑。


1
“思考和决定,不要让设计趋势为您考虑。” 不幸的是,如今愚蠢地跟随趋势变得非常普遍。有时阅读SO会因为趋势而得到所有相同的答案。
l00k

是的,我已经在许多主题上看到了这一点,当我意识到正在发生的事情时,有时我会停止争论。那时,每个人都为内容框比边界框更好感到疯狂。这是对IE表示仇恨的一种方式。然后出现了引导程序,突然每个人都是边防信徒。趋势来了,但是趋势就去了。使用goto,使用表格,使用iframe,只需知道您在做什么以及为什么。趋势主义者会尝试使您失望,然后他们在您的网站上注册并付款。世界再次拯救。
dkellner '19

@dkellner我不理解这一部分:“服务器至少需要知道某人是否已登录。(而且,如果您每次需要确定数据库时都在打扰数据库,那几乎注定要失败。”)假设您使用PHP将会话数据存储在数据库中。为什么要查询数据库的登录错误(变色是一个强词),因为无论如何都会有许多后续的数据库请求根据PHP会话ID来获取完整的用户数据和其他内容?换句话说,在任何情况下,数据库查询都是不可避免的。另外,如果您没有收到PHP会话ID,则说明该用户未经身份验证,无需查询。
user2923322

当您有成千上万甚至数百万个用户时,您就无法承受每次要执行Keepalive,位置更新,消息轮询或需要简短签入的操作时都无法连接到db的麻烦。您必须在没有数据库访问权限(或使用数据库访问权限最少的情况下)的情况下实现这些调用,这就是为什么我要说的是,如果您围绕db构建整个概念,可能会致命。同样,在某些情况下,精心设计的数据库解决方案会起作用,但是典型的程序员会通过说“好的,首先我们连接并获取一些用户信息”来解决任何问题。Baaaad练习。
dkellner


3

无状态与有状态之间的主要区别是每次都会将数据传递回服务器。在无状态的情况下,客户端必须提供所有信息,因此可能需要在每个请求中传递很多参数。在有状态中,客户端一次传递这些参数,然后由服务器维护,直到再次由客户端修改。

IMO,API应该是无状态的,这允许真正快速地扩展。


2

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

REST 无状态约束非常重要。如果不应用此约束,则服务器端应用程序将无法很好地扩展,因为维护每个客户端会话将是其致命弱点


如果您随每个请求发送身份验证数据,那么您将凭证存储在哪里/如何存储在客户端上,这样用户就不必在每个请求中都重新输入它?
琥珀色

1

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

另一个选择是在服务器上生成一个会话ID并将其发送给客户端,因此客户端将能够向服务器发送会话ID并进行身份验证。这比每次发送用户名和密码要安全得多,因为如果有人得到了他们的帮助,那么他/她就可以模拟用户,直到用户名和密码被更改为止。您可能会说,即使会话ID也可能被盗,在这种情况下,用户将被假冒,您是对的。但是,在这种情况下,只有在会话ID有效的情况下才可以冒充用户。

如果RESTful API需要用户名和密码来更改用户名和密码,那么即使有人使用会话ID冒充了用户,黑客也将无法锁定真实用户。

可以通过单向锁定(加密)某种方式(识别用户)并将会话时间添加到会话ID中来生成会话ID,这样就可以定义会话的到期时间。

服务器可以存储会话ID,也可以不存储会话ID。当然,如果服务器存储了会话ID,则它将违反问题中定义的条件。但是,仅重要的是确保可以为给定的用户验证会话ID,而不必存储会话ID。想象一下,您对电子邮件,用户ID和一些特定于用户的私人数据(如喜欢的颜色)进行单向加密,这将是第一级,并以某种方式将用户名日期添​​加到加密的字符串中,然后应用两个方式加密。结果,当接收到会话ID时,可以解密第二级,以便能够确定用户声称是哪个用户名以及会话时间是否正确。如果这是有效的,然后可以通过再次进行加密并检查其是否与字符串匹配来验证第一级加密。您不需要为此存储会话数据。


这是有道理的

0

整个概念是不同的...如果您尝试实现RESTFul协议,则无需管理会话。在这种情况下,最好对每个请求执行身份验证过程(但在性能方面会增加成本-哈希密码将是一个很好的例子。没什么大不了的……)。如果使用会话-如何在多台服务器之间分配负载?我敢打赌,RESTFul协议旨在消除任何会话-您实际上并不需要它们……这就是为什么它被称为“无状态”。仅在完成请求后您无法在客户端上存储Cookie以外的任何内容时才需要会话(以旧的,非Javascript / HTML5支持的浏览器为例)。如果使用“全功能” RESTFul客户端,通常可以安全存储base64(login:password) 在客户端(在内存中)上,直到应用程序仍然加载为止-该应用程序用于访问唯一的主机,并且第三方脚本不会破坏cookie。

我会强烈建议为RESTFul服务禁用Cookie身份验证...请查看基本/摘要身份验证-对于基于RESTFul的服务应该足够了。


3
什么是客户端a client side (in memory) 存储以及如何安全保存base64(login:password)在客户端?
RN库什瓦哈2015年

1
没有什么被定义为“完全安全”。但是,您可以考虑使用OAuth2提供比为API请求(基本Auth)保存base64字符串更好的安全性,如果坚持使用基本身份验证,则可以使用HTTPS以获得更好的安全性。
felixwcf

3
RN Kushwaha,当他们告诉您停止在服务器上存储会话并将其存储在客户端中时,似乎没人想回答这个问题。
BeniRose

0

REST是无状态的,并且在请求之间不维护任何状态。设置客户端Cookie /标头以维护用户状态(例如身份验证)。假设客户端的用户名/密码已通过第三方身份验证机制进行了验证-第二级OTP生成等。一旦用户通过身份验证-标头/ cookie停止了服务端点的暴露,由于用户附带有效的标头/ cookie,我们可以假定用户为auth 。现在,某些用户信息(如IP)要么保留在缓存中,然后在此之后,如果请求来自列出资源的同一Ip(mac地址),则允许用户。缓存会保留特定的时间,一旦经过一段时间就会失效。因此,可以使用缓存,也可以使用数据库条目来保留信息的黑白信息。


0

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

要管理会话或为用户提供自定义体验,它需要维护一些元数据或用户可能的用户偏好,过去的请求历史记录的状态。可以通过维护cookie,隐藏属性或将其保存到会话对象中来完成。

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

希望这可以帮助!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.