提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
前言
一、概述
什么是JWT?JSON Web Token(JWT),是一个开放安全的行业标准,用于多个系统之间传递安全可靠的信息。
二、JWT结构
JSON Web Token是一个token字符串。
它由三部分组成:
- 头部(Header):红色的为Header,指定token类型与签名类型。
- 载荷(playload):紫色的为载荷,存储用户id等关键信息。
- 签名(Signature):蓝色的为签名,保证整个信息的完整性、可靠性。
如下图 :
1.头部(Header)
JWT的头部用于描述关于该JWT的最基本的信息,例如:其类型以及签名所用的算法等。(这可以被表示成一个JSON对象)
{
"typ": "JWT",
"alg": "HS256"
}
在此,我们说明这是一个JWT,并且我们所用的签名算法是HS256算法。
对它进行Base64编码,之后的字符串就成了JWT的Header(头部)。
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
2.载荷(playload)
iss: 该JWT的签发者
sub: 该JWT所面向的用户
aud: 接收该JWT的一方
exp(expires): 什么时候过期,这里是一个Unix时间戳
iat(issued at): 在什么时候签发的
可以用一个JSON对象来描述以上属性。
将上面的JSON对象进行base64编码
可以得到下面的字符串,这个字符串我们将它称作JWT的Payload(载荷)。
eyJpc3MiOiIyOWZmMDE5OGJlOGM0YzNlYTZlZTA4YjE1MGRhNTU0NC1XRUIiLCJleHAiOjE1MjI0OTE5MTV9
3.签名(Signature)
HMACSHA256(base64UrlEncode(header) + "." +base64UrlEncode(payload),secret)
将上面的两个base64编码
后的字符串用句号连接在一起(头部在前),就形成了如下字符串。
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiIyOWZmMDE5OGJlOGM0YzNlYTZlZTA4YjE1MGRhNTU0NC1XRUIiLCJleHAiOjE1MjI0OTE5MTV9
最后,我们将上面拼接完的字符串用HS256算法进行加密。
在加密的时候,我们还需要提供一个密钥(secret)。
那么就可以得到我们加密后的内容(蓝色)。(这个就是我们JWT的签名了。)
P-k-vIzxElzyzFbzR4tUxAAET8xT9EP49b7hpcPazd0
三、签名的目的
最后一步签名的过程,实际上是对头部以及载荷内容进行签名。(一般而言,加密算法对于不同的输入产生的输出总是不一样的)
所以,如果有人对头部以及载荷的内容解码之后进行修改,再进行编码的话,那么新的头部和载荷的签名和之前的签名就将是不一样的。
而且,如果不知道服务器加密的时候用的密钥,得出来的签名也一定是不一样的。
服务器应用在接受到JWT后,会首先对头部和载荷的内容用同一算法再次签名。
那么服务器应用是怎么知道我们用的是哪一种算法呢?(别忘了,我们在JWT的头部中已经用alg字段指明了我们的加密算法了)
如果服务器应用对头部和载荷再次以同样方法签名之后发现,自己计算出来的签名和接受到的签名不一样,那么就说明这个Token的内容被别人动过的,我们应该拒绝这个Token,返回一个HTTP 401 Unauthorized响应。
四、JWT流程
- 客户端使用账户密码请求登录接口。
- 登录成功后服务器使用签名密钥生成JWT ,然后返回JWT给客户端。
- 客户端再次向服务端请求其他接口时带上JWT。
- 服务端接收到JWT后验证签名的有效性,对客户端做出相应的响应。
五、JWT与Session的区别
session实际上是基于cookie来传输的,最重要的session信息是存储在服务器的,所以服务器每次可以通过cookie中的sessionId获取到当前会话的用户,对于单台服务器这样做没问题,但是对于多台就涉及到共享session的问题了,而且认证用户的增多,session会占用大量的服务器内存。
jwt是存储在客户端的,服务器不需要存储jwt,jwt里面有用户id,服务器拿到jwt验证后可以获得用户信息.也就实现了session的功能。
相比session,jwt是无状态的,其不与任何机器绑定,只要签名秘钥足够的安全就能保证jwt的可靠性。
六、JWT方案中token的安全问题
按照JWT的流程,jwt是存储在客户端的,服务器不需要存储jwt;
客户端每次发送请求时携带token,然后到服务端验证token是否正确、是否过期,然后解码出携带的用户信息。
根据以上流程
如果token在传输过程被攻击者截取了,那么对方就可以伪造请求,利用窃取的Token模拟正常请求,实现用户的正常操作,而服务器端对此完全不知道,因为JWT机制是无状态的。
我们要明白JWT解决的是认证与授权的问题,上述劫持或者类似的中间人攻击是JWT不可避免的,也是其他认证与授权方式不可避免的。
想避免可以使用HTTPS。