如果您对基于令牌的身份验证感兴趣,那么此博客适合您。在此博客中,我主要针对基于令牌/无状态的身份验证,以及如何使用JWT(Json Web令牌)来实现。
无状态/基于令牌的身份验证
无状态身份验证意味着,在服务器端,我们不维护用户状态。服务器完全不知道谁发送了请求,因为我们不维护状态。我们可以通过使用JWT(JSON Web令牌)来实现无状态身份验证。但是在进入基于JWT和基于令牌的身份验证之前,让我们看一下过去使用会话cookie进行身份验证的方式。
状态 验证
这个怎么运作?
浏览器向服务器发出POST请求,其中包含用户的标识和密码。服务器以在用户浏览器上设置的cookie进行响应,该cookie包含用于标识用户的会话ID。在随后的每个请求中,服务器都需要找到该会话并将其反序列化,因为用户数据存储在服务器上。
状态验证的缺点
难以扩展: 服务器需要为用户创建会话并将其持久保存在服务器上的某个位置。如果我们有分布式系统,则必须确保会话在多个节点之间共享。
跨域资源共享(CORS): 使用AJAX调用从另一个域获取资源(跨域)时,我们可能会遇到禁止请求的问题,因为默认情况下,HTTP请求在跨域请求中不包含Cookie 。
与Web框架耦合: 使用基于服务器的身份验证时,我们将与我们框架的身份验证方案绑定在一起。在以不同编程语言编写的不同Web框架之间共享会话数据确实非常困难,甚至是不可能的。
无状态/基于令牌的身份验证
在无状态身份验证中,无需在会话中存储用户信息。我们可以轻松地使用相同的令牌从我们登录的域以外的域中获取安全资源。
这个怎么运作?
浏览器或移动客户端向身份验证服务器发出包含用户登录信息的请求。认证服务器生成一个新的JWT访问令牌,并将其返回给客户端。客户端需要存储该令牌并将每个请求发送到Authorization标头中的受限资源。然后,服务器验证令牌,如果令牌有效,则将安全资源返回给客户端。
基于令牌的身份验证的优点
无状态,易于扩展: 令牌包含标识用户的所有信息,无需会话状态。如果使用负载平衡器,则可以将用户传递到任何服务器,而不必绑定到我们登录的同一服务器。
可重用性:我们可以有许多单独的服务器,它们在多个平台和域上运行,并重复使用同一令牌来验证用户身份。构建与另一个应用程序共享权限的应用程序很容易。
性能: 没有服务器端查找来查找和反序列化每个请求的会话。我们要做的唯一一件事就是验证令牌并解析其内容。
什么是JSON Web令牌?
JSON Web令牌(JWT)是一种紧凑且独立的方法,用于在各方之间作为JSON对象安全地传输信息。由于此信息是经过数字签名的,因此可以被验证和信任。可以使用秘密(使用HMAC算法)或使用RSA的公/私钥对对JWT进行签名。
紧凑:由于尺寸较小,可以通过URL,POST参数或HTTP标头发送JWT。
自包含:有效负载包含有关用户的必需信息,因此我们可以减少一些数据库调用。
JSON Web令牌的结构
JSON Web令牌由三部分组成,这些部分由点(.)分隔,分别是
-
标头
-
有效载荷
-
签名
JSON Web令牌示例
1 |
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ0b3B0YWwuY29tIiwiZXhwIjoxNDI2NDIwODAwLCJodHRwOi8vdG9wdGFsLmNvbS9qd3RfY2xhaW1zL2lzX2FkbWluIjp0cnVlLCJjb21wYW55IjoiVG9wdGFsIiwiYXdlc29tZSI6dHJ1ZX0.yRQYnWzskCZUxPwaQupWkiUzKELZ49eM7oWxAQK_ZXw |
标头
标头通常由两部分组成:令牌的类型(即JWT)和所使用的哈希算法,例如HMAC SHA256或RSA。
有效载荷(索赔)
令牌的第二部分是有效负载,其中包含声明。索赔主要有两种:保留的索赔和私有的索赔。
保留的权利要求:这些是一组预定义的权利要求,不是强制性的,但建议使用,以提供一组有用的权利要求。其中一些是:iss (发行者),exp (到期时间),sub (主题),aud (受众)等。
私人声明:这些是为在各方之间共享信息而创建的自定义声明。
样本有效载荷可能是
1 2 3 4 5 6 7 8 9 |
{ "sub" : "sample_user", "Account" : { "userName" : "sample_user", "firstName" : "sample", "lastName" : "user", "emailId" : "sample_user@imaginea.com" } } |
签名
要创建签名部分,您必须获取编码的标头,编码的有效负载,机密,标头中指定的算法,并对其进行签名。
JWT的安全性和加密
如果我们想在JWT令牌中放入一些敏感信息,为了保护敏感信息,我们可以使用JSON Web加密(JWE)规范对JWT有效负载本身进行加密。