当前位置:  开发笔记 > 编程语言 > 正文

如何理解"RESTful API是无状态的"?

如何解决《如何理解"RESTfulAPI是无状态的"?》经验,为你挑选了1个好方法。

我听说了RESTful API should be stateless. All state info should be kept on client side.

但是当我从网页发出ajax调用时,我注意到会话ID cookie总是被发送到服务器.使用该会话ID,我可以在服务器上获取会话对象.因此,我可以get/set some state info in the session.

这会破坏code of being statelessRESTful API吗?

添加1

(我的问题的背景如下.)

我尝试通过调用RESTful API来实现登录页面以验证用户名和密码.

每次用户尝试访问我的站点的页面时,登录servlet filter将检查该用户的session(这是getSession()被调用的地方),以查看是否存在有效的登录信息.如果没有,登录过滤器会将用户重定向到登录页面.

在登录页面上,使用用户名和密码对服务器上的RESTful API进行ajax调用.根据RESTful API的返回结果,页面上的JavaScript将决定是否让用户进入我的网站.

所以,在这种情况下,我有点必须使用session.

详细代码位于此处: 此登录逻辑是否通过RESTful呼叫声音?



1> cassiomolin..:

简单地说:在REST应用程序中,每个请求必须包含服务器必须理解的所有信息,而不是依赖于服务器记住先前的请求.

在服务器上存储会话状态违反了REST体系结构的无状态约束.因此,会话状态必须完全由客户端处理.

继续阅读以了解更多详情.

会话状态

传统Web应用程序使用远程会话.在这种方法中,应用程序状态完全保留在服务器上.请参阅Roy T. Fielding的论文中的以下引文:

3.4.6远程会话(RS)

远程会话样式是客户端 - 服务器的变体,它试图最小化客户端组件而不是服务器组件的复杂性或最大化重用.每个客户端在服务器上启动会话,然后在服务器上调用一系列服务,最后退出会话.应用程序状态完全保留在服务器上.[...]

虽然这种方法带来了一些优势,但它降低了服务器的可扩展性:

远程会话风格的优点是更容易在服务器上集中维护接口,减少了在扩展功能时对部署的客户端中的不一致性的担忧,并且如果交互在服务器上使用扩展的会话上下文,则提高了效率.缺点是由于存储的应用程序状态,它降低了服务器的可伸缩性,并降低了交互的可见性,因为监视器必须知道服务器的完整状态.

无国籍约束

REST架构样式是在包含服务器无状态的集合约束的顶部定义.根据Fielding,REST 无状态约束定义如下:

5.1.3无国籍

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

此约束会导致可见性,可靠性可伸缩性的属性:

可见性得到改善,因为监控系统不必超出单个请求数据,以确定请求的完整性质.可靠性得到改善,因为它简化了从部分故障中恢复的任务.可扩展性得到改善,因为不必在请求之间存储状态允许服务器组件快速释放资源,并进一步简化实现,因为服务器不必管理跨请求的资源使用.

身份验证和授权

如果客户端请求需要身份验证的受保护资源,则每个请求都必须包含要经过适当身份验证/授权的所有必需数据.请参阅RFC 7235中的引用:

HTTP认证被认为是无状态的:认证请求所需的所有信息必须在请求中提供,而不是依赖于服务器记住先前的请求.

身份验证数据应属于标准HTTP Authorization标头.来自RFC 7235:

4.2.授权

Authorization报头字段允许用户代理本身与源服务器进行认证-通常,但不一定,在接收到后401(未授权)响应.其值由包含所请求资源领域的用户代理的认证信息的凭证组成.[...]

此HTTP标头的名称很不幸,因为它带有身份验证而不是授权数据.

对于身份验证,您可以使用基本HTTP身份验证方案,该方案将凭据作为用户名和密码对进行传输,使用Base64进行编码:

Authorization: Basic 

如果您不想在每个请求中发送用户名和密码,则可以将用户名和密码交换为在每个请求中发送的令牌(例如JWT).JWT可以包含用户名,到期日期以及可能与您的应用程序相关的任何其他元数据:

Authorization: Bearer 

你的服务器可能出了什么问题

一旦你有一个会话标识符,我想在你的应用程序的某个地方正在创建一个HTTP会话.它可以在您自己的代码中或您正在使用的框架代码中.

在Java应用程序中,必须确保调用以下方法:

HttpServletRequest#getSession()

HttpServletRequest#getSession(boolean)true


谢谢.所以基本上,如果我遵循RESTful方法,HTTP协议是我唯一的朋友.是的,我正在使用`HttpServletRequest.getSession()`调用.似乎技术本身并没有阻止我这样做(实际上它有点诱惑我这样做).我需要坚持"纪律".
@CássioMazzochi Molin,很好-我想我现在对此有所了解:这里的无状态确实意味着每个连接都是“新的”,从某种意义上说,我们不必“证明”发起会话的服务器在事先请求中(Cookie就是这种情况)。不可能在不同的请求之间“中断”一个“会话”,因为现在没有了。
@dinvlad确实如此。在RESTful应用程序中,没有服务器端会话这样的东西。以受保护的资源为目标时,请求必须带有要进行身份验证/授权的凭据。保护REST应用程序安全的常用方法是基于HTTPS的_basic authentication_。在这种方法中,客户端必须在每个请求中发送用户名和密码,然后服务器才能执行身份验证/授权。
@dinvlad在基于令牌的身份验证方案中,令牌成为用户的凭据。硬凭证(例如用户名和密码)被交换为必须在每个请求中发送的令牌,然后服务器可以执行身份验证/授权。令牌可以在短时间内有效,可以被撤消,可以携带范围详细信息(令牌可以要求的内容)等。
推荐阅读
无名有名我无名_593
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有