JSON Web Token(缩写 JWT)是目前最流行的跨域认证解决方案,本文介绍它的原理和用法。
- 跨域身份验证
Internet服务无法与用户身份验证分开。一般过程如下。
1.用户向服务器发送用户名和密码。
2.验证服务器后,相关数据(如用户角色,登录时间等)将保存在当前会话中。
3.服务器向用户返回session_id,session信息都会写入到用户的Cookie。
4.用户的每个后续请求都将通过在Cookie中取出session_id传给服务器。
5.服务器收到session_id并对比之前保存的数据,确认用户的身份。
-
JWT 的原理
当服务器接收用户的请求时,返回一个json对象。
例如
{
“name":"xxx",
"id":"guest"
"datatime":"xxxxx"
}
以后用户每次与服务器端进行交互时,都会使用这个json对象进行验证,为了防止篡改json,服务器端保存时会将json进行签名(signature)
-
JWT 的数据结构
进行签名后的JWT大概如下
aaa.bbb.ccc
三个部分每个部分都有特定的作用。
- Header(头部)
- Payload(负载)
- Signature(签名)
- Header
Header通常作为JWT的元数据表示方法如下
{ "alg": "HS256", "typ": "JWT" }
alg(algorithm)表示构造签名的算法,这里使用的是HMAC SHA256。
typ(type)表示JSON类型 这里是JWT
- Payload
Payload 部分也是一个 JSON 对象,用来存放实际需要传递的数据。JWT 规定了7个官方字段,供选用。
{
iss (issuer):签发人
exp (expiration time):过期时间
sub (subject):主题
aud (audience):受众
nbf (Not Before):生效时间
iat (Issued At):签发时间
jti (JWT ID):编号
}
除了规定的字符,还可以自定义内容,例如
{ "name":"xxx", "admin":"true" }
- Signature
Signature 部分是对前两部分的签名,防止数据篡改。
首先,需要指定一个密钥(secret)。这个密钥只有服务器才知道,不能泄露给用户。然后,使用 Header 里面指定的签名算法(默认是 HMAC SHA256),按照下面的公式产生签名。这里需要介绍一下默认算法的具体运算过程
HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
- 基于token验证与基于服务器验证
传统基于服务器验证的做法是将已经认证过的用户信息存储在服务器上,比如Session。用户下次请求的时候带着Session ID,然后服务器以此检查用户是否认证过。
这种基于服务器的身份认证方式存在一些问题:
- Sessions : 每次用户认证通过以后,服务器需要创建一条记录保存用户信息,通常是在内存中,随着认证通过的用户越来越多,服务器的在这里的开销就会越来越大。
- CORS : 当我们想要扩展我们的应用,让我们的数据被多个移动设备使用时,我们必须考虑跨资源共享问题。当使用AJAX调用从另一个域名下获取资源时,我们可能会遇到禁止请求的问题。
- CSRF : 用户很容易受到请求伪造攻击
- 基于token的身份验证
主要过程:
- 用户携带用户名和密码请求访问
- 服务器校验用户凭据
- 应用提供一个token给客户端
- 客户端存储token,并且在随后的每一次请求中都带着它
- 服务器校验token并返回数据
CTF:
CISCN2018 easyweb
非预期解: