摘要: Token 是在服务端产生的 。如果前端使用用户名/密码向服务端请求认证,服务端认证成功,那么在服务端会返回 Token 给前端 。前端可以在每次请求的时候带上 Token 证明自己的合法地位
不久前,我在在前后端分离实践中提到了基于 Token 的认证,现在我们稍稍深入一些 。
通常情况下,我们在讨论某个技术的时候,都是从问题开始 。那么第一个问题:
为什么要用 Token?
而要回答这个问题很简单——因为它能解决问题!
可以解决哪些问题呢?
- Token 完全由应用管理,所以它可以避开同源策略
- Token 可以避免 CSRF 攻击(http://dwz.cn/7joLzx)
- Token 可以是无状态的,可以在多个服务间共享
Token 是在服务端产生的 。如果前端使用用户名/密码向服务端请求认证,服务端认证成功,那么在服务端会返回 Token 给前端 。前端可以在每次请求的时候带上 Token 证明自己的合法地位 。如果这个 Token 在服务端持久化(比如存入数据库),那它就是一个永久的身份令牌 。
于是,又一个问题产生了:需要为 Token 设置有效期吗?
需要设置有效期吗?
对于这个问题,我们不妨先看两个例子 。一个例子是登录密码,一般要求定期改变密码,以防止泄漏,所以密码是有有效期的;另一个例子是安全证书 。SSL 安全证书都有有效期,目的是为了解决吊销的问题,对于这个问题的详细情况,来看看知乎的回答(http://dwz.cn/7joMhq) 。所以无论是从安全的角度考虑,还是从吊销的角度考虑,Token 都需要设有效期 。
那么有效期多长合适呢?
只能说,根据系统的安全需要,尽可能的短,但也不能短得离谱——想像一下手机的自动熄屏时间,如果设置为 10 秒钟无操作自动熄屏,再次点亮需要输入密码,会不会疯?如果你觉得不会,那就亲自试一试,设置成可以设置的最短时间,坚持一周就好(不排除有人适应这个时间,毕竟手机厂商也是有用户体验研究的) 。
然后新问题产生了,如果用户在正常操作的过程中,Token 过期失效了,要求用户重新登录……用户体验岂不是很糟糕?
为了解决在操作过程不能让用户感到 Token 失效这个问题,有一种方案是在服务器端保存 Token 状态,用户每次操作都会自动刷新(推迟) Token 的过期时间——Session 就是采用这种策略来保持用户登录状态的 。然而仍然存在这样一个问题,在前后端分离、单页 App 这些情况下,每秒种可能发起很多次请求,每次都去刷新过期时间会产生非常大的代价 。如果 Token 的过期时间被持久化到数据库或文件,代价就更大了 。所以通常为了提升效率,减少消耗,会把 Token 的过期时保存在缓存或者内存中 。
还有另一种方案,使用 Refresh Token,它可以避免频繁的读写操作 。这种方案中,服务端不需要刷新 Token 的过期时间,一旦 Token 过期,就反馈给前端,前端使用 Refresh Token 申请一个全新 Token 继续使用 。这种方案中,服务端只需要在客户端请求更新 Token 的时候对 Refresh Token 的有效性进行一次检查,大大减少了更新有效期的操作,也就避免了频繁读写 。当然 Refresh Token 也是有有效期的,但是这个有效期就可以长一点了,比如,以天为单位的时间 。
时序图表示
使用 Token 和 Refresh Token 的时序图如下:
1)登录
![深入了解 Token 认证的来龙去脉](http://img.jiangsulong.com/220403/1I40953E-0.jpg)
文章插图
【深入了解 Token 认证的来龙去脉】2)业务请求
![深入了解 Token 认证的来龙去脉](http://img.jiangsulong.com/220403/1I4092501-1.jpg)
文章插图
3)Token 过期,刷新 Token
![深入了解 Token 认证的来龙去脉](http://img.jiangsulong.com/220403/1I4095M6-2.jpg)
文章插图
上面的时序图中并未提到 Refresh Token 过期怎么办 。不过很显然,Refresh Token 既然已经过期,就该要求用户重新登录了 。
当然还可以把这个机制设计得更复杂一些,比如,Refresh Token 每次使用的时候,都更新它的过期时间,直到与它的创建时间相比,已经超过了非常长的一段时间(比如三个月),这等于是在相当长一段时间内允许 Refresh Token 自动续期 。
到目前为止,Token 都是有状态的,即在服务端需要保存并记录相关属性 。那说好的无状态呢,怎么实现?
无状态 Token
如果我们把所有状态信息都附加在 Token 上,服务器就可以不保存 。但是服务端仍然需要认证 Token 有效 。不过只要服务端能确认是自己签发的 Token,而且其信息未被改动过,那就可以认为 Token 有效——“签名”可以作此保证 。平时常说的签名都存在一方签发,另一方验证的情况,所以要使用非对称加密算法 。但是在这里,签发和验证都是同一方,所以对称加密算法就能达到要求,而对称算法比非对称算法要快得多(可达数十倍差距) 。
推荐阅读
- 计算机病毒是怎么进行传播?本文根据病毒分类带你了解传播的方式
- 深入理解C语言的指针
- 健身|了解几个减肥基础常识,搞不懂,很难真正瘦下来!
- 非洲菊的风水作用你了解吗
- 网络安全:你真的了解防火墙吗?
- IaaS、PaaS、SaaS三种云服务模式,你了解多少?
- 关于滇红茶冲泡步骤您了解吗?
- 1分钟了解手机蓝牙的宝藏功能!很多人只用过1个,剩下5个太神奇
- 华为手机找回功能了解一下:帮你找回手机
- 失而复得 华为“查找手机”功能有多强大?快来了解一下