无国界网络应用程序,都市传奇? [英] Stateless web application, an urban legend?

查看:149
本文介绍了无国界网络应用程序,都市传奇?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试理解基于令牌的身份验证这些天,它声称是无状态身份验证方法。我遇到了无状态网络应用程序的概念。

I am trying to understand token-based authentication these days, which claims to be a stateless authentication method. And I met the concept of stateless web application.

以下是我读过的一些主题:

Below are some threads I read about:

  • Use Spring MVC for Stateless web application development (no response yet)
  • Stateless Spring MVC
  • How to make a java web application fully stateless
  • How do I make my Web Application stateless yet still do something useful?

起初,我很高兴这个想法。但是越来越多我认为无状态伪命题

At first, I was thrilled at this idea. But more and more I think stateless is a pseudo-proposition.

例如,假设我们使用客户端存储的令牌进行身份验证,我们如何对在线用户进行统计(假设没有日志)?我们应该将令牌存储在DB中吗?这是不是意味着我们将状态信息存储在服务器上?更重要的是,DB中的名称,年龄等普通用户信息也是某种状态信息吗?

For example, suppose we use client-stored token for authentication, how can we make a statistic of online users (suppose there's no log)? Shall we store the token in DB? Doesn't that mean we store state info on server? And even more, is the plain user info such as name, age, etc. in DB also some kind of state info?

我认为这里的真正问题不是使网络应用程序成为无状态,但使网络应用程序正确处理状态信息,使其不会危及可扩展性

I think the real question here is not to make a web app stateless, but to make the web app properly handle the state info such that it won't jeopardize scalability.

这取决于关于如何解释单词无状态

That depends on how to interpret the word stateless:


  1. 网络应用程序没有状态。

  2. 或者网络应用程序不存储状态本身

  1. Web app doesn't have state.
  2. Or web app doesn't store state itself.

我更喜欢2,因为总有一些不可避免的全局状态(引自@ deceze对他的回答的评论)。无论我们将状态信息存储为HTML 5 Web存储,HTTP标头,隐藏表单字段还是Cookie,状态仍然存在。只是它存储在服务器以外的其他地方。

I prefer 2 because there can always be some inevitable global state (quoted from @deceze's comment to his answer). And no matter we store state info as HTML 5 web storage, or HTTP header, or hidden form fields, or Cookie, the state still exists. Only that it is stored somewhere other than on the server.

我错过了什么好东西?任何人都可以对此有所了解,这样我可以从这种心理上的挣扎中解脱出来吗?

Am I missing something great? Could anybody shed some light on this so I can be relieved from this mental struggle?

添加1

通过<$ c $阅读 RESTful Web Services 一书c> Leonard Richardson 。在第4章的无状态部分的末尾,它将状态分为应用程序状态资源状态。因此,我之前提到的普通用户信息和数据,如图像等,可以归类为资源状态无状态指的是应用程序状态。所以它不会破坏无状态代码来在服务器上存储资源状态

Just read about the book RESTful Web Services by Leonard Richardson. In chapter 4, at end of the section Statelessness, it classifies the state into Application State and Resource State. So the plain user info and data I mentioned before like images, etc. can be classified as Resource State. And what stateless refers to is Application State. So it doesn't break the code of stateless to store resource state on server.

但是这本书也提到了应用程序密钥用于限制用户调用Web服务的次数的场景。它承认此类信息无法存储在客户端。并且必须将其存储在服务器端会破坏无状态代码并引入会话亲和性问题。 它声称无状态可以避免会话亲和力问题但不解释如何。 我真的没有看到无状态如何处理这种情况。有人可以在这里说清楚吗?

But the book also mentions the scenario where an application key is used to restrict how many times a user can invoke a web service. It admits that such info cannot be stored on client side. And having to store it on server side breaks the code of stateless and introduce the issue of session affinity. It claims stateless can avoid session affinity issue but doesn't explain how. I really don't see how stateless can handle this scenario. Anyone could shed some light here?

推荐答案

状态只是指客户端和服务器。当然,服务器将存储数据,从技术上讲,您可以将服务器上任何数据的任何修改视为更改状态。因此,在这种意义上的无状态应用程序绝对没有实际意义。

The "state" only really refers to the state between the client and the server. Of course the server will store data, and technically you can see any modification of any data on the server as "altering state". Hence a "stateless" application in this sense makes absolutely no practical sense.

无状态指的是服务器是否在任何地方特定时间,允许特定客户向其发送特定请求的状态。

What "stateless" refers to is whether the server is, at any particular time, in a state to allow a particular client to send a particular request to it.

考虑:使用传统的基于cookie的方式登录会话,服务器只在状态下接受来自客户端的请求的有限时间窗口;只要当前会话有效。客户无法预测这是多久。任何时候,来自客户端的请求都可能失败,因为服务器上的某些状态超时。在这种情况下,客户端需要通过再次登录来重置服务器的状态。

Consider: with a traditional cookie-based login session, the server is only in a state to accept requests from the client for a limited time window; for as long as the current session is valid. The client cannot predict for how long that is. At any time, a request from the client may fail, because some state on the server timed out. In this case, the client needs to reset the server's state by logging in again.

将此与基于令牌的身份验证进行对比。令牌必须无限期有效。它本质上是用户名和密码的替代品。为了便于讨论,只需假设客户端在每次请求时都会发送用户名和密码。这意味着每个请求都可以根据自己的优点进行身份验证,而不需要服务器处于某种特定的时间状态。

Contrast this with token based authentication. The token must be valid indefinitely. It is essentially a substitution for a username and password. For the sake of discussion, just assume the client sends their username and password with every request. This means every request can be authenticated on its own merits, not requiring the server to be in some particular temporal "state".

您使用令牌而不是用户名的原因和密码是双重的:

The reason why you use tokens instead of usernames and passwords is twofold:


  1. 您可以使用同一帐户授权多个客户,但每个客户都使用其单独管理的凭据

  2. 您不希望每次请求都来回发送主密码

当然,服务器需要跟踪创建的令牌,并针对每个请求对某些数据库进行身份验证。这是一个不相关的实现细节。这与使用会话cookie没有区别;但是,由于令牌无限期有效,因此可以更轻松地缓存请求,而不需要复制临时会话存储。

最后一个需要抢占的潜在参数反击:无限期会话和无限期令牌之间的区别是什么,会话结束时与令牌可能被撤销的区别是什么?

会话结束时,可以使用其他会话重新建立主凭据(重新登录)。令牌可以/应该仅在主动撤销时结束,这类似于撤销完全针对主凭证访问服务的授权,并且不属于常规应用程序流的一部分。

One last potential argument that needs preemptive countering: what's the difference between an indefinite session and an indefinite token, and what's the difference when the session ends vs. when the token may be revoked?
When a session ends, it can be reestablished using some other "master credentials" (logging back in). A token can/should only end when actively revoked, which is akin to revoking the authorisation to access the service entirely for the master credentials, and is not something that is part of the regular application flow.

更一般地说:将无状态HTTP协议与FTP等有状态协议进行对比。在FTP中,服务器和客户端需要保持共享状态同步。例如,FTP协议有许多其他东西, c> CWD 命令更改当前工作目录。即,在任何给定时间都存在客户端所在目录的概念。后续命令的行为会有所不同,具体取决于所处的目录。这是有状态的。您不能在不知道该状态的情况下随意发送命令,否则您将无法预测结果将是什么。

Speaking more generally: contrast the stateless HTTP protocol with a stateful protocol like FTP. In FTP, the server and client need to keep a shared state in sync. For instance the FTP protocol has, among many other things, the CWD command to change the current working directory. I.e., there is a notion of what directory a client "is in" at any given time. Subsequent commands behave differently depending on what directory one is in. That is stateful. You can't arbitrarily send commands without being aware of that state, else you won't be able to predict what the outcome will be.

无状态客户端/服务器通信首先简化了客户端,因为客户端可以随时假设能够请求服务器的任何内容,而无需知道 state 服务器(我的会话是否仍处于活动状态?,此操作会影响什么目录?)。 它可以帮助扩展服务器实施,因为只需要在所有服务器之间复制静态信息,而不是不断变化的有效会话池及其相关数据。

Stateless client/server communication simplifies the client side first of all, since the client can assume at all times to be able to request anything of the server, without needing to know the state of the server ("is my session still active or not?", "what directory will this action affect?"). It can help scale out the server implementation since only static information needs to be replicated between all servers, instead of a constantly changing pool of valid sessions and their associated data.

在架构上,您的目标应该是拥有尽可能多的无状态组件。这将简化扩展。例如,如果您的Web服务器保留了本地会话存储,那么很难将Web服务器扩展到负载均衡器/ CDN后面的多个实例。一个改进是将会话存储集中到一个独立的数据库;现在,您可以拥有多个无状态 Web服务器,这些服务器知道如何从某处获取数据(包括会话数据)并可以呈现模板,但在其他方面完全可以互换。

Architecturally, your goal should be to have as many stateless components as possible. This will simplify scaling out. For example, if your web server is keeping a local session store, that makes it very hard to scale out your web server to multiple instances behind a load balancer/CDN. One improvement is to centralise the session store to an independent database; now you can have several stateless web servers which know how to get data (including session data) from somewhere and can render templates, but are otherwise completely interchangeable.

但是,会话商店必须与试图访问它的每个人保持完美同步,这使得很难扩展 it 令牌通过减少数据更改次数(仅在添加或删除令牌时)来改善这一点,这意味着如果您想在多个位置拥有多个令牌存储,则可以使用分布式数据库或其他更简单的复制机制,以及/或使数据可缓存。

However, a session store must be kept in perfect sync across everyone trying to access it, which makes it hard to scale it. Tokens improve this by making the data change less often (only when tokens are added or removed), which means you can use a distributed database or other simpler replication mechanism if you want to have several token stores in possibly multiple locations, and/or makes that data cacheable.

这篇关于无国界网络应用程序,都市传奇?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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