背景
公司处在前后端分离的转折阶段,作为后端人员,要找到一个适用于接口验证的方式,公司仍保持后端使用Laravel框架,而laravel框架默认的是【web】方式,web 方式是使用 session 来进行用户认证,当然也是可以使用,但是有一定的不安全,经过调研,主流使用的Token验证方式。
介绍JWT
JWT资料
JWT:全称Json Web Token,是一种规范化的token。可以理解为对token这一技术提出的一套规范,是在RFC 7519中提出的。
JWT的Token组成
The Anatomy of a JSON Web Token,这里详细介绍了什么是JWT、JWT的构成等。本篇部分内容摘自这里。
一个JWT token是一个字符串,它由三部分组成:header(头部)、payload(载荷)、signature(签名)
1.header
头部通常由两部分组成,令牌的类型(即JWT)和正在使用的签名算法(如:HMAC SHA256),例如:
{
"alg": "HS256",
"typ": "JWT"
}
然后使用Base64encode编码该json串得到头部,即xxxx
2.payload
载荷中存放了一些我们要传输的信息和其他有关令牌的信息,来帮助服务器理解这个tomen,同时也可以包含一些自定义的信息,用户信息交换等。不过数组越大,得到的token就会越长,所以不建议放太多数据。又因为载荷是用base64encode编码,相当于明文了,所以决定不能存密码等敏感信息。
载荷的属性分为三类:
- 预定义(registered)
- 公有(public)
- 私有(private)
预定义载荷
公有载荷
在使用 JWT 时可以额外定义的载荷。为了避免冲突,应该使用 IANA JSON Web Token Registry中定义好的,或者给额外载荷加上类似命名空间的唯一标识。
私有载荷
在信息交互的双方之间约定好的,既不是预定义载荷也不是公有载荷的一类载荷。这一类载荷可能会发生冲突,所以应该谨慎使用。(不过具体为啥会冲突,待了解)
{
"sub": "1", //主题
"iss": "http://localhost:8000/auth/login", // 签发人
"iat": 1451888119, //签发时间戳
"exp": 1454516119, //过期时间戳
"nbf": 1451888119, //生效时间戳,在此之前token无效
"jti": "37c107e4609ddbcc9c096ea5ee76c667", //编号
"aud": "dev" //受众
}
对上述json串同header一样,encode得到一个串,然后分到token的第二部分,载荷,即yyyy
3.signature
令牌第三部分由以下哈希组成:
- the header
- the payload
- secret
根据第一部分的加密方式进行加下,如果以HMACSHA256加密,如下:
$encode_string = base64UrlEncode(header) + "." + base64UrlEncode(payload);
$signature = HMACSHA($encode_string, 'secret');
上述得到的signature,在同第一步一样进行encode,就得到了第三部分,即zzzz
签名的作用:保证JWT没有被篡改过,原理如下:
HMAC 算法是不可逆算法,类似 MD5 和 hash ,但多一个密钥,密钥(即上面的 secret)由服务端持有,客户端把 token 发给服务端后,服务端可以把其中的头部和载荷再加上事先共享的 secret 再进行一次 HMAC 加密,得到的结果和 token 的第三段进行对比,如果一样则表明数据没有被篡改。
写在最后
其实真正集成使用的时候,基本没有修改过这些东西,毕竟自己还是个菜鸟,所以记录一份,了解一下
【前程栽树,后人乘凉】
JWT超详细分析
JWT-Auth了解
JWT 完整使用详解