什么是JWT(Json web token):
JWT是目前最流行的跨域认证解决方案。基于json的开放标准(RFC7用于519),以token的方式代替传统的session-cookie模式,用于服务器,客户端传递信息签名验证。
传统的cookie-session鉴权:
1. 客户端使用用户名和密码登录
2. 服务器端验证账号密码通过后,在session里保存一些数据(比如说用户UID,登录时间等等)
3. 服务器向用户返回一个session_id,写入用户的cookie中
4. 此后用户的每一次请求都用 把cookie中的这个sessioni_d传给服务器
5. 服务器接收到session_id 找到之前保存的数据就可以知道用户有没有登录
传统方式的缺点:
1. session通常放在内存中,用户数量如果过大会对服务器产生压力
2. 扩展性。 哪怕session以文件形式保存,放在redis中。对于分布式系统来说会产生高流量的数据读取(文件同步读取问题)
3. 容易受到csrf攻击
JWT的验证方式:
1. 客户端使用用户名和密码的方式请求登录
2. 服务器验证账号和密码的真伪,如果通过后会返回一个token给客户端
3. 客户端收到token之后缓存起来,比如放在浏览器中的Local Stage中,之后的每次请求都会携带token
4. 服务器收到token之后,进行验证。通过验证则返回数据
JWT的优点:
1. 服务器不用session了,变为无状态。减小了开支
2. jwt构成简单,占用很少的字节
3. json格式通用。不用语言之间都可以处理
JWT的结构:
jwt头部:
{
'typ': 'JWT', // 这个token的类型:默认jwt,写死
'alg': 'HS256' // 签名的算法,默认是HMAC SHA256
}
然后将头部进行base64编码, 构成了第一部分:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
载荷payload:
载荷也是一串json,用来存放实际需要传递的数据。他由三部分组成
官方标准的字段声明(JWT规定了7个官方标准字段,非必填。为了紧凑。声明名称都是三个字符的缩写)
iss: jwt签发者
sub: jwt所面向的用户
aud: 接收jwt的一方
exp: jwt的过期时间,这个过期时间必须要大于签发时间
nbf: 定义在什么时间之前,该jwt都是不可用的.
iat: jwt的签发时间
jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。
公共的字段声明
私有的字段声明
定义一个payload: (这里是不加密的,不要放敏感数据)
{
"user_name": "John Doe",
"user_id": 10
}
BASE64后的结果: eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9
签名signature:
JWT的第三部分是一个签证(签名)信息,即对前两部分签名后得到的一个字符串。
签名:使用密钥(SECRECT_KEY )对数据进行加密,得到了一个值(签名)。
签名的作用:防止数据篡改,客户端传给服务器的jwt如果被修改过,服务器验签(校验)会不通过。
base64UrlEncode:
Base64编码 使用的字符包括大小写字母各26个,加上10个数字,和加号“+”,斜杠“/”,一共64个字符,等号“=”用来作为后缀用途。
为了更好地在url上传递,=可以省略,+替换为- ,/替换为_
JWT的使用:
1.http头部加上 Authorize:bearer token
2. 直接url后面通过一个get参数传递
JWT校验真伪:
1. 服务器收到JWT
2. 将header和payload 用秘钥和对应的算法生成签名
3. 判断生成的签名和jwt的第三部分是否一致
4. 一致则代表可信,不一致则返回错误
网友评论