我正在构建一个包含多个服务器的RESTful API,我想知道可以将访问令牌存储在中央数据库服务器中,然后,对于每个请求,通过查询数据库并执行给定的操作来验证此访问令牌是否有效.
如果我使用会话来完成这项工作,那么它会变成非RESTful吗?就像我将会话数据存储在数据库中一样?这对我来说一直是个令人困惑的想法.
REST代表Representational State Transfer,这个架构由Roy Thomas Fielding在他的论文第5章中定义.
Fielding为REST架构定义了一组约束.其中一个限制是客户端和服务器之间的无状态通信,定义如下(他的论文中没有重点):
[...]从客户端到服务器的每个请求必须包含理解请求所需的所有信息,并且不能利用服务器上任何存储的上下文.因此,会话状态完全保留在客户端上.[...]
因此,如果您在服务器上保持会话状态,则会破坏无状态约束.因此,它不是REST.在REST中,您将无法在服务器上进行会话,因此您将没有会话标识符.
从客户端到服务器的每个请求都必须包含服务器要理解的所有必要信息.有了它,您不依赖于存储在服务器上的任何会话上下文.
例如,在访问需要身份验证的受保护资源时,每个请求必须包含所有必要的数据才能进行正确的身份验证/授权.这意味着将对每个请求执行身份验证.
请查看RFC 7235中有关新身份验证方案注意事项的引用:
HTTP身份验证框架的某些方面对新身份验证方案的工作方式施加了限制:
- HTTP认证被认为是无状态的:认证请求所需的所有信息必须在请求中提供,而不是依赖于服务器记住先前的请求.[...]
身份验证数据(凭据)应属于标准HTTP Authorization标头.来自RFC 7235:
的
Authorization报头字段允许用户代理本身与源服务器进行认证-通常,但不一定,在接收到后401(未授权)响应.其值由包含所请求资源领域的用户代理的认证信息的凭证组成.Run Code Online (Sandbox Code Playgroud)Authorization = credentials[...]
请注意,此HTTP标头的名称很不幸,因为它带有身份验证数据而不是授权.无论如何,这是发送凭据的标准标头.
执行基于令牌的身份验证时,令牌是您的凭据.在此方法中,您的硬凭证(用户名和密码)将交换为在每个请求中发送的令牌.同样,必须对每个请求执行身份验证,因此您不会利用服务器上的任何存储上下文.
将您的令牌存储在服务器的某个位置是完全有效的.它不会破坏REST架构的无状态约束.
基本上,标记可以是不透明的(除了值本身之外没有显示任何细节,如随机字符串)或者可以是自包含的(如JSON Web标记):
随机字符串:可以通过生成随机字符串并将其持久保存到具有过期日期和与之关联的用户标识符的数据库来发出令牌.
JSON Web令牌(JWT):由RFC 7519定义,它是在两方之间安全地表示声明的标准方法.JWT是一个自包含的令牌,使您能够在有效负载中存储用户标识符,到期日期和任何您想要的(但不存储密码),这是一个编码为Base64的JSON.客户端可以读取有效负载,并且可以通过验证服务器上的签名来轻松检查令牌的完整性.如果您不需要跟踪JWT令牌,则无需持久保存JWT令牌.尽管如此,通过持久存在令牌,您将有可能使其无效并撤销其访问权限.要找到一些与JWT合作的优秀资源,请查看http://jwt.io.
有许多数据库可以保存令牌.根据您的要求,您可以探索不同的解决方案,例如关系数据库,键值存储或文档存储.
您的 RESTful API 需要是无状态的。无状态意味着它不应该依赖于事先的通信,例如在相关请求之前设置身份验证和 cookie 的情况。
但这并不意味着您不能在服务器端缓存某些身份验证令牌,前提是客户端可以在没有它的情况下发出请求。这一切都意味着,如果客户端可以在每个请求上回退到标准 HTTP 身份验证,那么它应该仍然没问题。这样做的目标是实现负载平衡、分布,并且在服务器端不使用(或限制)内存进行对话。
除此之外,如果您不打算使用它提供的好处,那么您实际上不需要遵守所有“规则” 。如果您愿意,您可以以任何您想要的方式实现它,只要知道权衡即可。
编辑:找到之前关于该主题的讨论:会话真的违反 RESTful 吗?
| 归档时间: |
|
| 查看次数: |
5430 次 |
| 最近记录: |