Token的安全存储与传输
Token是什么
究竟什么才算是Token,我一直没有找到比较好的定义,但是回过头来看一下它的翻译,才明白,原来名字就是定义了,Token就是令牌。
那么什么是令牌呢?
先看一下我们现实生活中的令牌。
为什么它是个令牌呢?因为六扇门可以验证其真实性,同时六扇门可以从中获取持有该令牌的人的身份。
从这里我们就可以给Token下一个大致的定义:
可以被某个服务认证其真实性。
该服务可以从中获取用户的信息。
也就是说SessionID是Token,JWT也是Token。
基于Token的认证流程
大致就分为几步:
- 用户发送登陆请求到服务器,携带用户名和密码登陆。
- 服务器收到请求后验证其正确性,如果认证成功,就返回一个Token给前端
- 前端收到Token之后存储下来,接下来每个请求都带上Token
- 服务器从请求中拿出Token,验证其有效性以及对应的用户信息或者权限等,如果认为可以发起这个请求再进行处理。
这几个步骤看起来很简单,但是可以有很多的升级版,比如
第一步的登陆用OAuth协议去做,那就是我们常见的第三方登陆,如果对OAuth有疑惑的可以看一下OAuth协议设计。
第二步如果选择将信息存储在服务器Session,并返回一个SessionID,那么Token就是SessionID,如果服务器不进行任何存储,而是选择将部分用户信息加密签名丢回给前端,那就可以用JWT。
第三步中Token的存储有很多方案,比如Cookie,LocalStorage,SessionStorage等,甚至是USB Token,从安全,性能,成本等方面考虑这些方案的优缺点是什么。
还有虽然我们可以通过签名的方式保证Token的不可篡改,但是整个过程中如何保证我们的Token不被窃听?
除此之外,我们还可以考虑一下为什么第二步有时候返回两个token,如果看了上面提到的OAuth协议设计应该对这个问题会有答案。
Token的几个存储方案比较
Cookie
cookie是大家最熟悉的前端存储方案。大家对它的一些特性很熟悉,比如同源限制,自动携带等等。那这里就主要说它的几个安全方面的配置:
- http-only:这个参数限定只能通过请求自动携带的方式获取cookie,没办法通过脚本去获取,这样一来就可以有效避免cookie被xss攻击,及时你的页面被不小心注入脚本,也无法获取你的cookie。
- same-site:这个属性规定,只有请求是从同源页面发起才能获取cookie。这个主要是用来防御csrf的,因为如果只要是同源请求就可以自由携带cookie的话,很容易就遭受csrf攻击,比如在token失效之前打开了攻击者页面,该页面自动向后台发送请求,就会携带cookie。
- secure:这个参数可以让cookie只会被https请求携带,https应该是是目前最好用的几种防止中间人攻击的方式之一,可以有效防止你的token被窃听。
其他前端存储方案
SessionStorage:sessionStorage 特别的一点在于,即便是相同域名下的两个页面,只要它们不在同一个浏览器窗口中打开,那么它们的 sessionStorage 内容便无法共享;
LocalStorage:在同源的所有标签页和窗口之间共享数据,保存的数据长期存在,下一次访问该网站的时候,网页可以直接读取以前保存的数据。
IndexDB:类似LocalStorage,只不过容量大很多
硬件级别的Token保护:USB Token
将Token存储在独立的硬件上,重要请求需要用户自主填写Token。
USB Key中也可以存储数字证书,这个最常见的应该就是网银的U盾了。
比较
SessionStorage安全性较高,能比较好防御CSRF,但是对XSS无用,且局限较大。
LocalStorage和IndexDB受同源保护,但是一旦被注入脚本也很危险。
USB Key安全性较高,属于物理级别的防御,但是有一定的成本。
Cookie最方便,但是默认状态下最不安全,需要将http-only,same-site,secure等开启才能有较高的安全性。
Token的安全传输与HTTPS
准确地讲HTTPS是协议栈。
最上层是HTTP,接着是SSL/TLS,接着是TCP。
HTTP的数据包在进入TCP发送缓存之前被SSL/TLS加密就叫做HTTPS。
所以想要搞明白HTTPS,就要搞明白HTTP。而HTTP协议本身并不复杂,它的复杂体现在各种header上,这些header都是 一些应用上的设计,所以这一层叫应用层。
想要搞懂HTTP,最好是搞懂TCP。
我整理了几篇关于TCP和HTTPS的博客,它们是我在学习是一些疑惑的解答。
在看的时候如果带着我的这些问题可能会更好:
HTTP协议是什么?用于获取万维网服务器资源的协议,基于TCP,熟知端口是80 。
TCP协议是什么?传输层可靠传输协议,缓存上层协议不断发送的数据然后打包发送给不可靠的IP协议,通过一系列措施进行可靠传输,流量控制和拥塞控制,最重要的是面向连接的特性,这也是加密数据不会混淆的重要基础。
SSL/TLS如何加密数据?用对称秘钥。
对称秘钥如何生成?为什么不用非对称?对称秘钥就是每次TCP握手阶段用非对称秘钥生成的。
如何保证公钥的真实性?证书。
如何验证证书的有效性?根证书,证书链。
这里是链接地址: