Token
token的意思是“令牌”,是用户身份的验证方式,当用户第一次登录后,服务器生成一个token并将此token返回给客户端,客户端保存此token,之后请求只需带上这个token前来请求数据即可,无需再次带上用户名和密码,服务端收到请求,然后去验证客户端请求里面带着token,如果验证成功,就向客户端返回数据。
一、有效期
需要有效期:在登录中,一般要求定期更改密码,以防泄漏;安全认证SSL证书有有效期,目的是为了解决吊销问题
有效期多长:
①若太短,10s,息屏则要重新输入密码,不合理;根据用户体验,一般为1周
②在1周情况下,到期时用户正在使用,就让登录,不合理
方案一:服务端保存token状态,用户每次操作就自动刷新时间(类似session)。存在的问题是若前后端分离,一直刷新,时间成本高;若持久化到数据库中,代价更大。为了减少消耗,一般放在缓存或内存中。
方案二:Refresh Token,来避免频繁读写。一旦过期,前端使用Refresh Token来申请新Token
二、无状态
所有状态信息放在 Token上,服务器可以不保留 Token,但服务器需要验证 Token有效。
因为签发和验收都是服务器方,所以可以用对称加密算法。
这样做引发的问题:若使用无状态token,还需要记录在有效期内主动注销的token,很麻烦,一般不这样做。
解决方式:前端注销,就丢掉本地保存的 Token和 Refresh Token。这样服务器收到的就是一定是没注销的。
三、分离认证服务
可见,虽然认证和业务分离了,实际即并没产生多大的差异。当然,这是建立在认证服务器信任业务服务器的前提下,因为认证服务器产生 Token 的密钥和业务服务器认证 Token 的密钥和算法相同。换句话说,业务服务器同样可以创建有效的 Token。
四、可以避免 CSRF
CSRF 攻击原理
你这可以这么理解CSRF攻击:攻击者盗用了你的身份,以你的名义发送恶意请求。CSRF能够做的事情包括:以你名义发送邮件,发消息,盗取你的账号,甚至于购买商品,虚拟货币转账…造成的问题包括:个人隐私泄露以及财产安全。
五、防御CSRF
1.验证 HTTP Referer 字段
从原理图我们知道,攻击的来源是来自第三方网站,如果我们能判断当前HTTP请求的来源地址,并只允许来自本网站的的请求才能访问,那么CSRF攻击就失效了。根据 HTTP 协议,在 HTTP 头中有一个字段叫 Referer,它记录了该 HTTP 请求的来源地址,要防御 CSRF 攻击,wan.sogou.com网站只需要对于每一个请求验证其 Referer 值,如果是以wan.sogou.com 开头的域名,则说明该请求是来自搜狗游戏(再来一波广告)自己的请求,是合法的。如果 Referer 是其他网站的话,则有可能是黑客的 CSRF 攻击,拒绝该请求。
**优点:**简单易行,开发人员不需要操心 CSRF 的漏洞,只需要在最后给所有安全敏感的请求统一增加一个拦截器来检查 Referer 的值就可以,不需要改变当前系统的任何已有代码和逻辑,没有风险。
**缺点:**Referer的值是由浏览器提供的,相当于安全性都依赖于第三方(即浏览器)来保障,实际上某些浏览器可以被篡改Referer的值。
2. token
CSRF攻击之所以能够成功,是因为攻击者可以完全伪造用户的请求,该请求中所有的用户验证信息都存在cookie中,因此攻击者可以在不知道这些验证信息的情况下直接利用用户自己的cookie来通过安全验证。要防止CSRF,关键在于在请求中放入黑客所不能伪造的信息,并且该信息不存在于cookie之中。可以在HTTP请求中以参数的形式加入一个随机产生的token,并在服务器建立一个拦截器来验证这个token,如果请求中没有token或者token不正确,则认为可能是CSRF攻击而拒绝该请求。
现在业界一致的做法就是使用Anti CSRF Token来防御CSRF。
①用户访问某个表单页面。
②服务端生成一个Token,放在用户的Session中,或者浏览器的Cookie中。
③在页面表单附带上Token参数。
④用户提交请求后,服务端验证表单中的Token是否与用户Session(或Cookies)中的Token一致,一致为合法请求,不是则非法请求。
这个Token值必须是随机的,不可预测的。由于Token的存在,攻击者无法再构造一个带有合法Token的请求实施CSRF攻击。另外使用Token应注意Token的保密性,尽量把敏感操作由GET改成POST,以form或者AJAX形式提交,避免Token泄露。