我的应用程序流如下:
- 客户端应用程序首先通过发送用户名/密码请求令牌(令牌资源)
- 客户端应用程序将存储该令牌,然后让用户登录(如果凭据有效)
- 现在客户端应用程序将使用令牌执行剩余的api调用
- 一旦用户注销,我们就会从客户端内存中删除令牌,并使服务器中的令牌无效
在一次采访中,我被问到这不是一个纯粹的RestFull标准,因为现在所有的资源都依赖于令牌资源,即在调用任何api之前,客户端必须调用令牌api,在这种情况下,资源将变得紧密耦合和排序。根据rest标准,所有资源都应该是独立的。
所以我的问题是:
1.有了token,我的资源如何独立
2.使用代币是非标准方式吗?那么为什么很多应用程序都在使用令牌呢
一种方法是使用基本身份验证和api而不是令牌,但这样我就必须将用户名和密码存储在客户端应用程序中,直到登录为止。在客户端应用程序中保存密码是不安全的。
快速查看REST约束
老实说,我认为令牌没有任何问题,只要应用程序没有打破Roy Thomas Fielding关于REST:的论文第5章中定义的约束集
- 客户端服务器
- 无国籍
- 缓存
- 统一接口
- 分层系统
- 按需编码
让我们看看无状态约束:
5.1.3无状态
[…]从客户端到服务器的每个请求都必须包含理解请求所需的所有信息,并且不能利用服务器上存储的任何上下文。因此,会话状态完全保留在客户端上。[…]
如果您正在访问需要身份验证的受保护资源,则每个请求都必须包含要进行正确身份验证/授权的所有必要数据,从而在客户端上保持会话状态。
当你不想为每个请求通过网络发送硬凭据(如用户名和密码)时,基于令牌的身份验证方案非常好。使用令牌时,硬凭据会发送一次,然后交换为每个请求中必须发送的令牌。然后,该令牌成为凭证,并且可以在一定时间内有效。
请注意,您选择的身份验证方案并不重要,您的服务器需要验证每个请求中发送的凭据。
JSON Web令牌(JWT)
这是在RFC 7519中定义的用于在双方之间安全地表示声明的标准方法。JWT是一个自包含的令牌,使您能够将用户标识符、过期日期和您想要的任何内容(但不存储密码)存储在有效负载中,该有效负载是一个编码为Base64的JSON。
客户端可以读取有效负载,并且可以通过在服务器上验证令牌的签名来轻松检查令牌的完整性。
要找到一些与JWT合作的优秀资源,请查看http://jwt.io.
跟踪代币
JWT允许您执行无状态身份验证,也就是说,如果不需要跟踪JWT令牌,则不需要持久化它们。
尽管如此,通过持久化令牌,您将有可能使对它们的访问无效和撤销。为了跟踪JWT令牌,如果需要,可以保留令牌标识符(jti
声明)和一些元数据(为其颁发令牌的用户、过期日期等),而不是保留整个令牌。
您的应用程序可以提供一些撤销令牌的功能,但在用户更改密码时,请始终考虑撤销令牌。
在持久化令牌时,请始终考虑删除旧令牌,以防止数据库无限期增长。