什么是JWT
TOKEN
token 是一串字符串,通常因为作为鉴权凭据,最常用的使用场景是 API 鉴权。
API 鉴权
API鉴权的方式有以下几种
-
cookie + session
和平常 web 登陆一样的鉴权方式 -
HTTP Basic
将账号和密码拼接然后 base64 编码加到 header
头中。很显然,因为账号和密码几乎是『明文』传输的,而且每次请求都传,安全性可想而知。
所以,这种方式是好少使用的
- HTTP Digest
将账号和密码加上其他一些信息拼接然后取摘要加到 header 头中。
不过其实最大的问题还是:每次请求都要对账号、密码取一次摘要,也就是说每次请求都要有账号和密码,也就是说账号和密码要么缓存一下,要么就每次请求要去用户输一次密码,这样显然不合适。
- Token
token通过一次登录验证,得到一个鉴权字符串,然后以后带着这个鉴权字符串进行后续操作,这样就可以解决每次请求都要带账号密码的问题,而且也不需要反复使用账号和密码。
CSRF 攻击
构成这个攻击的原因,就在于 Cookie + Session 的鉴权方式中,鉴权数据(cookie 中的
session_id)是由浏览器自动携带发送到服务端的,借助这个特性,攻击者就可以通过让用户误点攻击链接,达到攻击效果。而 token
是通过客户端本身逻辑作为动态参数加到请求中的,token 也不会轻易泄露出去,因此 token 在 CSRF 防御方面存在天然优势
JWT 的组成
JWT 全称 JSON Web Tokens ,是一种规范化的 token。可以理解为对 token 这一技术提出一套规范,是在 RFC 7519 中提出的
组成
一个 JWT token 是一个字符串,它由三部分组成,头部、载荷与签名,中间用 . 分隔,例如:xxxxx.yyyyy.zzzzz
头部(header)
头部通常由两部分组成:令牌的类型(即 JWT)和正在使用的签名算法(如 HMAC SHA256 或 RSA.)。
例如:
{
"alg": "HS256",
"typ": "JWT"
}
载荷(Payload)
载荷中放置了 token 的一些基本信息,以帮助接受它的服务器来理解这个 token。同时还可以包含一些自定义的信息,用户信息交换
载荷的属性也分三类:
- 预定义(Registered)
- 公有(public)
- 私有(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):编号
签名(Signature)
签名时需要用到前面编码过的两个字符串,如果以 HMACSHA256 加密
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret
)
加密后再进行 base64url 编码最后得到的字符串就是 token 的第三部分 zzzzz。
组合便可以得到 token:xxxxx.yyyyy.zzzzz。
JWT 的使用有两种方式
- 加到 url 中:?token=你的token
- 加到 header 中,建议用这种,因为在 https 情况下更安全:Authorization:Bearer 你的token
JWT 在客户端的存储有三种方式
- LocalStorage
- SessionStorage
- Cookie [不能设置 HTTPonly]
值得注意的是,Cookie的这种方式有的移动端是不支持的,但是我们可以配合其他方式去使用
最推荐的还是第三种,因为第一二种存在跨域读取限制,而 Cookie 使用不同的跨域策略
Cookie 的跨域策略
子可以读父,但是父不可以读子,兄弟之间不能互相访问
a.xxx.com 和 b.xxx.com 可以读 xxx.com,
但是 a.xxx.com 和 b.xxx.com不能互相读取,
xxx.com 也不能读 a.xxx.com 和 b.xxx.com 的
关于 token 十件必须知道的事
- Token 获取到后需要保存起来以便下次使用,可以选择存储在 localstorage /sessionstorage/cookie
- Token 是包含有效期的,你必须部署一些逻辑来进行有效期的控制
- localstorage /sessionstorage 的跨域限制较 cookie 更为严格,推荐使用 cookie
- 在你进行异步请求时,浏览器一般都会发送预检请求(option),后端应对此部署相应的逻辑
- 为什么会有 OPTIONS 请求 - 云 + 社区 - 腾讯云
- 使用 cookie 可以轻松处理一个文件下载请求,但是 token 一般都是通过 XHR
方式进行请求的,所以你必须部署额外的逻辑。比如生成一个实时 ticket ,以 ticket 进行访问,然后校验,重定向,最后下载文件。 - 处理 XSS 比处理 CSRF 更容易(这一点我实在没看到他是什么个逻辑,大家可以去看看原文)
- token 在每次请求时都会被编码到请求中,所以请注意 token 的大小,不要编码过多数据
- 如果在 token 中编码敏感信息,请对 token 进行加密
- JSON Web Token 可以用于 Oauth2.0 的 Bearer Token 中,赋予 Oauth2.0 无状态的优势
本文转载于 skyArony
版权声明:
作者:linrux
链接:https://www.tot7.cn/technology/php/174.html
来源:Code林
文章版权归作者所有,未经允许请勿转载。
共有 0 条评论