基于session 的方式存在的问题
-
服务器端需要存储
session
,并且由于Session
需要经常快速查找,所以通常存储在内存中,或者内存数据库中。如果同时又大量用户在线,就会占用大量的服务器资源 -
当需要扩展时候,创建
session
的服务器可能不是验证session
的服务器,所以还需要将所有session
单独存储并共享,后来又有人想到,把所有的seesionid
放到同一台电脑上,让所有的用户都访问这同一台电脑,但是如果那个存储sessionid
的服务器挂掉了,那就要让所有的用户都得重登。 -
由于客户端使用
cookie
储存SessionID
, 在跨域场景下需要进行兼容性处理,同时这些方法也难以方法CSRF
攻击
Token 认证模式
基于 session
存在的这些问题,所有就有人在想,凭什么让我去保存这些该死的 sessionId,让用户自己存就好了,那么当用户把 认证信息传过来的时候,我怎么判断这个是我颁发的,还是他自己伪造的?这其实就变成了一个验证的问题。
Token 的流程
- 服务端使用用户名、密码进行认证
- 服务端验证用户名、密码正确以后,生成
Token
返回给客户端 - 客户端保存
Token
,访问需要认证的接口时,在 url 参数或HTTP Header
中加入Token
- 客户端通过解码
Token
进行鉴权,返回给客户端需要的数据
Token 的优势
可扩张性
在客户端存储的Tokens是无状态的,并且能够被扩展。基于这种无状态和不存储Session信息,负载负载均衡器能够将用户信息从一个服务传到其他服务器上。
安全性
请求中发送token而不再是发送cookie能够防止CSRF(跨站请求伪造)。即使在客户端使用cookie存储token,cookie也仅仅是一个存储机制而不是用于认证。不将信息存储在Session中,让我们少了对session操作。
token是有时效的,一段时间之后用户需要重新验证。我们也不一定需要等到token自动失效,token有撤回的操作,通过token revocataion可以使一个特定的token或是一组有相同认证的token无效。
可扩展性
使用tokens时,可以提供可选的权限给第三方应用程序。当用户想让另一个应用程序访问它们的数据,我们可以通过建立自己的API,得出特殊权限的tokens。