jwt由三部分组成,这些部分由点(.)分隔。
1):标头
头部通常由两部分组成:令牌的类型(即 JWT)和正在使用的签名算法(如 HMAC SHA256 或 RSA.)。
2):载荷
载荷中放置了 token 的一些基本信息,以帮助接受它的服务器来理解这个 token。同时还可以包含一些自定义的信息,用户信息交换。
载荷的属性也分三类:
2.1:预定义(Registered)
2.2:公有(public)
2.3:私有(private)
预定义的载荷
{
"sub": "1",
"iss": "http://localhost:8000/auth/login",
"iat": 1451888119,
"exp": 1454516119,
"nbf": 1451888119,
"jti": "37c107e4609ddbcc9c096ea5ee76c667",
"aud": "dev"
}
这里面的前 7 个字段都是由官方所定义的,也就是预定义(Registered claims)的,并不都是必需的。
iss (issuer):签发人
sub (subject):主题
aud (audience):受众
exp (expiration time):过期时间
nbf (Not Before):生效时间,在此之前是无效的
iat (Issued At):签发时间
jti (JWT ID):编号
2.2:共有载荷:在使用 JWT 时可以额外定义的载荷。为了避免冲突,应该使用 IANA JSON Web Token Registry 中定义好的,或者给额外载荷加上类似命名空间的唯一标识。
2.3:在信息交互的双方之间约定好的,既不是预定义载荷也不是公有载荷的一类载荷。这一类载荷可能会发生冲突,所以应该谨慎使用。
3):签名(Signature)
签名时需要用到前面编码过的两个字符串,如果以 HMACSHA256 加密,就如下:
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret
)
加密后再进行 base64url 编码最后得到的字符串就是 token 的第三部分 zzzzz。
组合便可以得到 token:xxxxx.yyyyy.zzzzz。签名的作用:保证 JWT 没有被篡改过
JWT 的使用有两种方式:
加到 url 中:?token=你的token
加到 header 中,建议用这种,因为在 https 情况下更安全:Authorization:Bearer 你的token
JWT 在客户端的存储有三种方式:
LocalStorage
SessionStorage
Cookie [不能设置 HTTPonly]
但是最推荐的还是第三种,因为第一二种存在跨域读取限制,而 Cookie 使用不同的跨域策略
因为没开 HTTPonly,所以要注意防范 XSS 漏洞。
Cookie 的跨域策略:
子可以读父,但是父不可以读子,兄弟之间不能互相访问。
a.xxx.com 和 b.xxx.com 可以读 xxx.com,但是 a.xxx.com 和 b.xxx.com 不能互相读取,xxx.com 也不能读 a.xxx.com 和 b.xxx.com 的。
你可能会想:存 Cookie 那我不是又变得和 cookie + session 一样了吗?
其实不然,因为存 cookie 在这只是用到了其存储机制,而没有利用其去鉴权。也就是说我只是简单存一下,并没有期望浏览器带上去 token 去鉴权,将 token 加入请求这部分操作还是我手动进行的。
[资料来源:](https://www.cnblogs.com/DeadBoy/p/11481146.html)
原文:https://www.cnblogs.com/libinshenbg/p/14062737.html