会话真的违反rest吗?

在RESTful API中使用会话真的违反了RESTful吗?我看到了许多意见,但我不相信会议是不安分的。在我看来:

  • rest不禁止身份验证(否则在RESTful服务中几乎没有用处)
  • 身份验证是通过在请求中发送一个身份验证令牌来完成的,通常是头
  • 这个身份验证令牌需要以某种方式获得,并且可能会被撤销,在这种情况下需要更新
  • 身份验证令牌需要由服务器验证(否则就不是身份验证)

那么会话是如何违背这一点的呢?

  • 客户端,会话是使用cookie实现的
  • cookie只是一个额外的HTTP报头
  • 会话cookie可以在任何时候获得和撤销
  • 如果需要,会话cookie可以有无限的生存时间
  • 会话id(身份验证令牌)在服务器端得到验证

因此,对于客户端来说,会话cookie与任何其他基于HTTP报头的身份验证机制完全相同,只是它使用Cookie报头而不是Authorization或其他一些专有报头。如果没有附加到cookie值服务器端的会话,为什么会有区别呢?服务器端实现不需要关心客户端,只要服务器的行为 RESTful即可。因此,cookie本身不应该成为API 不安分的,会话只是客户机的cookie。

我的假设错了吗?什么使会话cookie 不安分的?

158907 次浏览

首先,REST不是宗教,不应该被当作宗教来对待。虽然REST式服务有很多优点,但您应该只在应用程序有意义时才遵循REST的原则。

也就是说,身份验证和客户端状态并不违反REST原则。虽然REST要求状态转换是无状态的,但这是指服务器本身。REST的核心是关于文档。无状态背后的思想是服务器是无状态的,而不是客户机。任何发出相同请求(相同的报头、cookie、URI等)的客户端都应该被带到应用程序中的相同位置。如果网站存储用户的当前位置,并通过更新这个服务器端导航变量来管理导航,那么就违反了REST。另一个具有相同请求信息的客户端将被带到不同的位置,具体取决于服务器端状态。

谷歌的web服务是RESTful系统的一个极好的例子。它们要求在每个请求时都传递一个带有用户身份验证密钥的身份验证头。这稍微违反了REST原则,因为服务器正在跟踪身份验证密钥的状态。必须维护此密钥的状态,并且它具有某种到期日期/时间,超过该日期/时间就不再授予访问权限。然而,正如我在文章开头提到的,为了让应用程序实际工作,必须做出牺牲。也就是说,身份验证令牌的存储方式必须允许所有可能的客户端在有效时间内继续授予访问权。如果一个服务器管理身份验证密钥的状态,以至于另一个负载均衡服务器无法接管基于该密钥的请求,那么您就开始真正违反REST原则了。谷歌的服务确保,在任何时候,您都可以在您的手机上对负载均衡服务器A使用身份验证令牌,并从您的桌面访问负载均衡服务器B,并且仍然可以访问系统,如果请求相同,则可以定向到相同的资源。

归根结底,您需要确保您的身份验证令牌是针对某种类型的备份存储(数据库、缓存等)进行验证的,以确保您尽可能多地保留REST属性。

我希望你能理解。如果你还没有检查关于具象国家转移的维基百科文章限制部分,你也应该检查一下。关于REST的原则实际上在争论什么以及为什么争论,它特别具有启发性。

  1. 会话不是不安分的
  2. 你是说REST服务只用于http还是我弄错了?基于cookie的会话只能用于自己的(!)基于http的服务!(这可能是一个问题与cookie工作,例如从移动/控制台/桌面/等)
  3. 如果你为3d开发者提供RESTful服务,永远不要使用基于cookie的会话,而是使用令牌来避免安全问题。

cookie不是用于身份验证的。为什么要重新发明轮子?HTTP具有设计良好的身份验证机制。如果我们使用cookie,我们就只能使用HTTP作为传输协议,因此我们需要创建自己的信号系统,例如,告诉用户他们提供了错误的身份验证(使用HTTP 401是不正确的,因为我们可能不会像HTTP规范要求的那样向客户端提供Www-Authenticate:))。还应该注意的是,Set-Cookie只是给客户的建议。它的内容可能会被保存,也可能不会被保存(例如,如果cookies被禁用),而Authorization报头会在每次请求时自动发送。

另一点是,要获得授权cookie,您可能需要首先在某个地方提供您的凭据。如果是这样,那不就是不安分吗?简单的例子:

  • 你试试没有cookie的GET /a
  • 你得到了一个授权请求
  • 你可以像POST /auth这样授权
  • 你得到Set-Cookie
  • 你试试GET /a cookie。但在这种情况下GET /a是否表现为幂等?

综上所述,我认为如果我们访问某些资源并且需要验证,那么我们必须验证在同一资源上,而不是其他任何地方。

首先,让我们定义一些术语:

  • < p > rest式:

    我们可以描述符合REST约束的应用程序 本节描述为“RESTful”.[15]如果服务违反了任何

    . {/p> .

    .根据维基百科
  • < p >无状态的约束:

    接下来,我们在客户端-服务器交互中添加一个约束: 通信在本质上必须是无状态的,如 图5-3第3.4.3节的CSS (client-stateless-server)样式, 这样,从客户端到服务器的每个请求必须包含所有的 了解请求所必需的信息,且不能获取 服务器上任何存储上下文的优势。会话状态为 因此完全保存在客户端

    根据菲尔丁的论文.

    .

所以服务器端会话违反了REST的无状态约束,RESTfulness也一样。

因此,对于客户端来说,会话cookie与任何会话cookie完全相同 其他基于HTTP头的身份验证机制,除了它使用 Cookie报头,而不是授权或其他 专有的头。< / p >

通过会话cookie,您可以将客户端状态存储在服务器上,因此您的请求具有上下文。让我们尝试向系统中添加一个负载均衡器和另一个服务实例。在这种情况下,您必须在服务实例之间共享会话。这样的系统很难维护和扩展,所以扩展性很差……

在我看来,饼干并没有什么错。cookie技术是一种客户端存储机制,存储的数据被每个请求自动附加到cookie头。我不知道REST约束在这种技术上有什么问题。所以技术本身没有问题,问题在于它的使用。菲尔丁写了一个小节关于他为什么认为HTTP cookie是坏的。

在我看来:

  • rest不禁止身份验证(否则在RESTful服务中几乎没有用处)
  • 身份验证是通过在请求中发送一个身份验证令牌来完成的,通常是头
  • 这个身份验证令牌需要以某种方式获得,并且可能会被撤销,在这种情况下需要更新
  • 身份验证令牌需要由服务器验证(否则就不是身份验证)

你的观点很可靠。唯一的问题是在服务器上创建身份验证令牌的概念。你不需要那部分。您所需要的是在客户端存储用户名和密码,并在每次请求时发送它。你只需要HTTP基本认证和加密连接就可以做到这一点:

-可信任客户端无状态认证”></p>


<ul>
<li><em>图1。—可信客户端无状态认证</li></em>
</ul>


<p>您可能需要在服务器端使用内存中的身份验证缓存来提高速度,因为您必须对每个请求进行身份验证。</p>


<p>对于您编写的可信客户端来说,这非常有效,但对于第三方客户端呢?他们不能拥有用户名和密码以及用户的所有权限。因此,您必须单独存储第三方客户端可以由特定用户拥有的权限。因此,客户端开发者可以注册他们的第三方客户端,并获得一个唯一的API密钥,用户可以允许第三方客户端访问他们的部分权限。比如阅读姓名和电子邮件地址,或者列出他们的朋友,等等……在允许第三方客户端访问后,服务器将生成一个访问令牌。第三方客户端可以使用这些访问令牌来访问用户授予的权限,如下所示:</p>


<p><img src=

实际上,正如通用资源标识符所指示的那样,RESTfulness只应用于资源。因此,在REST中谈论诸如头文件、cookie等都是不合适的。REST可以在任何协议上工作,即使它通常是在HTTP上完成的。

主要的决定因素是:如果您发送一个REST调用(它是一个URI),那么一旦调用成功地到达服务器,假定没有执行转换(PUT、POST、DELETE),该URI是否返回相同的内容?这个测试将排除错误或正在返回的身份验证请求,因为在这种情况下,请求还没有到达服务器,这意味着servlet或应用程序将返回与给定URI对应的文档。

同样,在POST或PUT的情况下,是否可以发送给定的URI/有效负载,并且无论发送多少次消息,它都将始终更新相同的数据,以便后续的get将返回一致的结果?

REST是关于应用程序数据的,而不是关于传输数据所需的低级信息。

在下面这篇博文中,Roy Fielding对整个REST思想做了一个很好的总结:

http://groups.yahoo.com/neo/groups/rest-discuss/conversations/topics/5841 < a href = " http://groups.yahoo.com/neo/groups/rest-discuss/conversations/topics/5841 " > < / >

"一个RESTful系统从一个稳态发展到 接下来,每一个这样的稳态都是一个潜在的启动状态 还有一个可能的终态。也就是说,RESTful系统是未知的 遵循一组简单规则的组件的数量 总是处于REST状态或从一个REST状态过渡 状态转换为另一个RESTful状态。每一种状态都可以完全 由它所包含的表示法和集合来理解 它提供的转换,其中转换限制为 统一的行动集合是可以理解的。系统可能是 一个复杂的状态图,但是每个用户代理只能看到 每次一种状态(当前稳态),因此每一种状态 状态很简单,可以独立地进行分析。用户OTOH, 能够在任何时候创建自己的过渡(例如,进入 一个URL,选择一个书签,打开一个编辑器等等)。" < / p >


至于身份验证的问题,无论它是通过cookie还是报头完成的,只要信息不是URI和POST有效负载的一部分,它就与REST完全没有关系。因此,关于无状态,我们只讨论应用程序数据。

例如,当用户在GUI屏幕上输入数据时,客户端会跟踪哪些字段已经输入,哪些字段没有输入,哪些必需的字段丢失等等。这都是CLIENT CONTEXT,服务器不应该发送或跟踪。发送到服务器的是需要在IDENTIFIED资源中(通过URI)修改的完整字段集,以便在该资源中发生从一个RESTful状态到另一个RESTful状态的转换。

因此,客户端会跟踪用户正在做什么,并且只向服务器发送逻辑上完整的状态转换。

HTTP事务,基本访问认证,不适合RBAC,因为基本访问认证每次都使用加密的username:password进行标识,而RBAC中需要的是用户希望用于特定调用的Role。

. RBAC不验证用户名权限,但验证角色权限

您可以像这样进行连接:usernameRole:password,但这是一种糟糕的做法,而且效率也很低,因为当一个用户拥有更多角色时,身份验证引擎将需要在连接中测试所有角色,并且每次调用都需要再次测试。这将破坏RBAC最大的技术优势之一,即非常快速的授权测试。

因此,使用基本的访问身份验证无法解决这个问题。

为了解决这个问题,会话维护是必要的,根据一些回答,这似乎与REST相矛盾。

这就是我喜欢REST不应被视为宗教的答案。在复杂的业务案例中,例如在医疗保健领域,RBAC是绝对常见和必要的。如果他们不被允许使用REST,那将是一个遗憾,因为所有的REST工具设计者都将REST视为一种宗教。

对我来说,在HTTP上维护会话的方法并不多。可以使用带有sessionId的cookie,也可以使用带有sessionId的报头。

如果有人有别的想法,我很乐意听听。

我认为令牌必须包括所有需要的信息编码在它里面,这使得认证通过验证令牌和解码信息 # EYZ0 < / p >

不,使用会话并不一定违反restful。如果您坚持REST规则和约束,那么使用会话(维护状态)将是多余的。毕竟,RESTfulness要求服务器不维护状态。

据我所知,当我们谈论会话时,有两种类型的状态

  • 客户端和服务器交互状态
  • 资源状态

这里的无状态约束指的是Rest中的第二种类型。使用cookie(或本地存储)并不违反Rest,因为它与第一个相关。

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

这里的问题是,服务器上要完成的每个请求都需要来自客户端的所有必要数据。那么这就被认为是无状态的。再说一遍,我们这里说的不是饼干,我们说的是资源。