2016-12-06 80 views
0

我正在开发一个相当复杂的带有Angular2前端的Web应用程序。我想维护所有客户端与服务器之间的通信,使用基于Node.js的RESTful API来传递JSON对象。使用REST API管理复杂应用程序的状态

但是,我对REST应该是无状态的要求有些困惑。在服务器端存储或生成相当多的数据,并将其存储在客户端并将其附加到每个请求都会产生相当大的开销。

例如:有数百个与特定用户相关的权限(即哪个资源可以在什么级别访问)。通过未加密的客户端执行这些权限是一个明显的安全问题;用每个请求重新提交所有的数据(加密)感觉很奇怪。在每次请求时从数据库刷新它们都会导致性能下降。

我的意思是,当然至少有一些类型的访问令牌,在身份验证时生成,必须通过每个请求传递给服务器。我只是假设我会生成一个不可猜测的会话ID(仅在成功验证时),并将它以http-only(限制JavaScript访问),安全(强制使用https)Cookie和使用此cookie传递给客户端在服务器端保持一些节约的会话状态(如权限)。但是,这种做法似乎在REST世界中被忽略了?是一个有状态的RESTful API是一个矛盾的,一个异端?

回答

2

不过,我对此感到REST应该是无状态的要求有些困惑

如有疑问,请查看论文 - 在这种情况下,菲尔丁是什么stateless意味着非常清楚:

通信本质上必须是无状态的,这样每个从客户端到服务器的请求都必须包含理解请求所需的所有信息,并且不能利用任何st在服务器上存储上下文。会话状态因此完全保留在客户端上。

换句话说,没有代词。他在描述Client-Stateless-Server architecture

时描述了主要优点,这些约束改进了可见性,可靠性和可伸缩性的属性。可见性得到改进,因为监控系统不必超越单个请求数据,以确定请求的全部性质。可靠性得到改善,因为它减轻了部分故障恢复的任务。由于不需要在请求之间存储状态,可扩展性得到了改进,使服务器组件可以快速释放资源并进一步简化实施。

客户端无状态服务器的缺点是它可能会通过增加一系列请求中发送的重复数据(每个交互开销)来降低网络性能,因为这些数据不能在共享上下文中留在服务器上。

我们不假定服务器托管纯函数; 当然服务器端存在状态。在大多数情况下,使用REST api的目的是提供一个接口,以适应Web的服务器端状态(以任何形式)。

例如:有几百个与某个用户相关的权限(即哪个资源可以在什么级别访问)。通过未加密的客户端执行这些权限是一个明显的安全问题;用每个请求重新提交所有的数据(加密)感觉很奇怪。在每次请求时从数据库刷新它们都会导致性能下降。

服务器缓存一些自己的状态没有什么根本性的错误,作为优化来提高后续调用的响应时间。这一切都隐藏在界面后面,并且完全不影响REST约束。 (如果下一个请求被路由到另一个服务器,您将得到缓存未命中和第二次查找,但这些不会以任何方式改变请求的含义。)

但是服务器不应该制作对客户状态的任何假设,因为它不能看到发生了什么;在没有通知服务器(后退按钮,请求由中间组件处理,请求由同一服务器的其他副本管理)的情况下,客户端状态可以改变。

另一方面,客户端在发送任何给定消息时确切知道客户端处于什么状态;它管理会话。任何相关的会话数据都会被客户端复制到请求中,服务器将处理请求内容及其自身状态,而不会记录先前的请求。