写在前面:
上一篇文章
幸运的金荷,公众号:我这一路我和我的项目之整合Security
对Security做了初步的介绍。了解其大致运行原理。归结起来可以用下面这张图进行概括。
但落地到实际项目中还是存在着不少缺陷。例如token安全问题。
Ps:完整项目请访问我码云地址https://gitee.com/lth1024/Security
Token
【定义】
token 是一串字符串,通常因为作为鉴权凭据,最常用的使用场景是API鉴权。
【常见的API 鉴权】
1.cookie + session
和平常 web 登陆一样的鉴权方式,很常见。
2.HTTP Basic
将账号和密码拼接然后base64 编码加到 header 头中。很显然,因为账号和密码几乎是『明文』传输的,而且每次请求都传,安全性可想而知。
3.HTTP Digest
每次请求都要对账号、密码取一次摘要,也就是说每次请求都要有账号和密码,也就是说账号和密码要么缓存一下,要么就每次请求要去用户输一次密码,这样显然不合适。同样,上面的 Basic 也存在这样的问题。
4.Token
token 通过一次登录验证,得到一个鉴权字符串,然后以后带着这个鉴权字符串进行后续操作,这样就可以解决每次请求都要带账号密码的问题,而且也不需要反复使用账号和密码。
【Token的优势】
Token 相对于 Cookie + Session 的优点,主要有下面两个:
①CSRF 攻击
这个原理不多做介绍,构成这个攻击的原因,就在于Cookie + Session 的鉴权方式中,鉴权数据(cookie 中的 session_id)是由浏览器自动携带发送到服务端的,借助这个特性,攻击者就可以通过让用户误点攻击链接,达到攻击效果。而token是通过客户端本身逻辑作为动态参数加到请求中的,token 也不会轻易泄露出去,因此token在CSRF 防御方面存在天然优势。
②适合移动应用
移动端上不支持cookie,而token只要客户端能够进行存储就能够使用,因此token在移动端上也具有优势。
【Token的种类】
自定义的token:开发者根据业务逻辑自定义的token
JWT:JSON Web Token,定义在 RFC 7519 中的一种token规范
Oauth2.0:定义在 RFC 6750 中的一种授权规范,但这其实并不是一种 token,只是其中也有用到 token
JWT
【定义】
JWT 全称JSON Web Tokens,是一种规范化的 token。可以理解为对 token 这一技术提出一套规范,是在 RFC 7519 中提出的。
【组成】
一个 JWT token 是一个字符串,它由三部分组成,头部、载荷与签名,中间用 . 分隔。
头部(header)
头部通常由两部分组成:令牌的类型(即 JWT)和正在使用的签名算法(如 HMAC SHA256 或 RSA.)
载荷(Payload)
载荷中放置了token 的一些基本信息,以帮助接受它的服务器来理解这个 token。同时还可以包含一些自定义的信息,用户信息交换。
载荷的属性也分三类:
预定义(Registered)
公有(public)
私有(private)
签名(Signature)
签名时需要用到前面编码过的两个字符串,如果以 HMACSHA256 加密,就如下:
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret
)
加密后再进行 base64url 编码。最后得到的字符串就是 token 的第三部分 zzzzz。
组合便可以得到 token:xxxxx.yyyyy.zzzzz
签名的作用:保证 JWT 没有被篡改过:
HMAC 算法是不可逆算法,类似 MD5 和 hash ,但多一个密钥,密钥(即上面的 secret)由服务端持有,客户端把 token 发给服务端后,服务端可以把其中的头部和载荷再加上事先共享的 secret 再进行一次 HMAC 加密,得到的结果和 token 的第三段进行对比,如果一样则表明数据没有被篡改。 |
【使用】
JWT 的使用有两种方式:
加到 url 中:?token=你的token
加到 header 中,建议用这种,因为在 https 情况下更安全:Authorization:Bearer 你的token
具体项目可以git pullgit@gitee.com:lth1024/Security.git拆箱即用。