会话是否确实违反RESTfulness?

在RESTful API中使用会话确实违反RESTfulness? 我看到很多意见都朝着任何一个方向发展,但我并不认为会议是无休止的。 从我的观点:

  • 对于RESTfulness,不会禁止认证(否则RESTful服务几乎没有用处)
  • 认证是通过在请求中发送认证令牌来完成的,通常是头部
  • 这个身份验证令牌需要以某种方式获得并且可能会被撤销,在这种情况下需要更新
  • 身份验证令牌需要服务器验证(否则它不会是身份验证)
  • 那么会话如何违反这个规定?

  • 客户端,会话使用cookie来实现
  • cookie只是一个额外的HTTP头
  • 一个会话cookie可以在任何时候被获取和撤销
  • 如果需要,会话cookie可以有无限的生命时间
  • 会话ID(身份验证令牌)在服务器端进行验证
  • 因此,对于客户端来说,会话​​cookie与任何其他基于HTTP头的认证机制完全相同,只不过它使用Cookie头而不是Authorization或其他专有头。 如果没有会话附加到cookie值服务器端,那为什么会有所作为? 只要服务器的行为是RESTful,服务器端实现就不需要关注客户端。 因此,Cookie本身不应该使API变得无法使用,并且会话只是客户端的Cookie。

    我的假设错了吗? 什么使得会话cookie无效?


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

  • REST风格:

    可以将符合本节中描述的REST约束的应用程序表征为“RESTful”[15]。 如果某个服务违反了所需的任何约束,则不能将其视为RESTful。

    根据维基百科。

  • 无状态约束:

    我们接下来为客户端 - 服务器交互添加一个约束:通信本质上必须是无状态的,如第3.4.3节(图5-3)中的客户端无状态服务器(CSS)样式,以便每个来自客户端的请求服务器必须包含理解请求所需的所有信息,并且不能利用服务器上存储的任何上下文。 会话状态因此完全保留在客户端上。

    根据菲尔丁论文。

  • 因此,服务器端会话违反了REST的无状态约束,因此也是RESTfulness。

    因此,对于客户端来说,会话​​cookie与任何其他基于HTTP头的认证机制完全相同,只不过它使用Cookie头而不是授权或其他专有头。

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

    在我看来,饼干没有问题。 Cookie技术是一种客户端存储机制,其中存储的数据通过每个请求自动附加到Cookie标头。 我不知道这种技术存在问题的REST约束。 所以技术本身没有问题,问题在于它的使用。 菲尔丁写了一篇关于他认为HTTP cookies不好的小节。

    从我的观点:

  • 对于RESTfulness,不会禁止认证(否则RESTful服务几乎没有用处)
  • 认证是通过在请求中发送认证令牌来完成的,通常是头部
  • 这个身份验证令牌需要以某种方式获得并且可能会被撤销,在这种情况下需要更新
  • 身份验证令牌需要服务器验证(否则它不会是身份验证)
  • 你的观点非常稳固。 唯一的问题是在服务器上创建身份验证令牌的概念。 你不需要那部分。 您需要的是在客户端上存储用户名和密码,并随每次请求发送。 与HTTP基本认证和加密连接相比,您不需要做更多的事情:

    图1.  - 受信任客户端的无状态身份验证

  • 图1. - 受信任客户端的无状态身份验证
  • 您可能需要服务器端的内存授权缓存才能使事情更快,因为您必须验证每个请求。

    现在,由您编写的值得信赖的客户端可以很好地工作,但第三方客户端又如何? 他们不能拥有用户名和密码以及用户的所有权限。 因此,您必须单独存储第三方客户端可以由特定用户拥有的权限。 因此,客户端开发人员可以注册他们的第三方客户端,并获得唯一的API密钥,用户可以允许第三方客户端访问其部分权限。 就像读取名称和电子邮件地址,或列出他们的朋友等等......在允许第三方客户端后,服务器将生成访问令牌。 这些访问令牌可以被第三方客户端用来访问用户授予的权限,如下所示:

    图2.  - 第三方客户端的无状态身份验证

  • 图2. - 第三方客户端的无状态身份验证
  • 因此,第三方客户端可以从可信客户端(或直接从用户)获取访问令牌。 之后,它可以通过API密钥和访问令牌发送有效的请求。 这是最基本的第三方认证机制。 您可以在每个第三方认证系统的文档中阅读更多关于实施细节的信息,例如OAuth。 当然这可能更复杂也更安全,例如,您可以在服务器端签署每个请求的详细信息,并将请求与请求一起发送,等等......实际的解决方案取决于您的应用程序的需要。


    首先,REST不是宗教,不应该这样接近。 虽然RESTful服务具有优势,但只要遵循REST的原则,只要它们对您的应用程序有意义即可。

    也就是说,身份验证和客户端状态不会违反REST原则。 尽管REST要求状态转换是无状态的,但这是指服务器本身。 在心里,所有REST都是关于文档的。 无国籍背后的想法是服务器是无国籍的,而不是客户。 任何发出相同请求的客户端(相同的头文件,cookie,URI等)应该被带到应用程序中的相同位置。 如果网站通过更新此服务器端导航变量来存储用户的当前位置和托管导航,则会违反REST。 根据服务器端状态,具有相同请求信息的另一个客户端将被带到不同的位置。

    Google的Web服务是RESTful系统的一个很好的例子。 它们需要一个带有用户身份验证密钥的身份验证头部,以便在每次请求时传递。 这确实违反了REST原则,因为服务器正在跟踪身份验证密钥的状态。 该密钥的状态必须保持不变,并具有某种到期日期/时间,之后不再授予访问权限。 但是,正如我在帖子的顶部所提到的,必须作出牺牲才能让应用程序实际工作。 也就是说,身份验证令牌必须以允许所有可能的客户端在其有效时间内继续授予访问权限的方式进行存储。 如果一个服务器正在管理身份验证密钥的状态,以至于另一个负载均衡服务器无法接管基于该密钥的请求,则您已经开始真正违反REST的原则。 Google的服务可以确保您随时可以将您在手机上使用的身份验证令牌应用于负载均衡服务器A,并从桌面访问负载均衡服务器B,并且仍然可以访问系统,并且可以将其定向到相同的资源请求是相同的。

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

    我希望所有这些都有道理。 如果还没有,你还应该查看关于具象状态传输的维基百科文章的约束部分。 对于REST的原则实际上是在争论什么和为什么,这特别具有启发性。


    Cookies不用于身份验证。 为什么重塑一个车轮? HTTP具有设计良好的认证机制。 如果我们使用cookie,我们只能使用HTTP作为传输协议,因此我们需要创建自己的信令系统,例如告诉用户他们提供了错误的身份验证(使用HTTP 401将是不正确的,因为我们可能不会提供Www-Authenticate给客户端,因为HTTP规范要求:))。 还应该注意的是, Set-Cookie只是客户端的一个建议。 其内容可能被保存(例如,如果cookie被禁用),而每个请求都会自动发送Authorization标头。

    另一点是,要获得授权cookie,您可能首先需要在某处提供凭据? 如果是这样,那么它会不会是RESTless? 简单的例子:

  • 你尝试GET /a没有cookie
  • 以某种方式获得授权请求
  • 你去和授权以某种方式像POST /auth
  • 你得到Set-Cookie
  • 您尝试使用cookie GET /a 。 但是GET /a在这种情况下表现得如何?
  • 总结一下,我相信如果我们访问某个资源并且需要进行身份验证,那么我们必须在同一个资源上进行身份验证,而不是其他任何地方。

    链接地址: http://www.djcxy.com/p/3737.html

    上一篇: Do sessions really violate RESTfulness?

    下一篇: Laravel Rest Authentication when post via HttpClient Android