Token
Token “令牌”的意思,是由服务端生成的一串字符串,作为客户端进行请求时身份验证的一个标识。
Token进行身份验证的简单流程:
- 用户第一次登录系统时,需要使用用户名和密码。
- 服务端接收到用户名与密码,进行身份验证,如果验证通过。
- 服务端生成一个token字符串,服务端把token字符串保存到服务端的内存中(流行使用将Token信息保存到Redis中),并将该token字符串返回给客户端。
- 客户端将服务端返回的token字符串保存到本地,如:Cookie或Local Storage(本地存储)。
- 当客户端再次向服务端发送请求的时候,需要带上token字符串,一起发送到服务端。
- 服务端收到带有token的请求之后,与本地的缓存中的token字符串进行对比。
- 如果验证通过,返回请求需要的结果信息。如果验证失败,返回提示信息。
Token简单组成
uid(用户唯一的身份标识)、time(当前时间的时间戳)、sign(签名,token的前几位以哈希算法压缩成的一定长度的十六进制字符串。为防止token泄露)。
Token是在服务端产生的。如果前端使用用户名密码向服务端请求认证,服务端认证成功,那么在服务端会返回Token给前端。前端可以在每次请求的时候带上Token证明自己的合法地位。如果这个Token在服务端持久化(如存入数据库),那么就是一个永久的身份令牌了。
Token的有效期
当我们登录优快云的时候,如果我们的密码长期未修改,系统会提示我们定期修改密码,这样为了防止用户名/密码泄露,带来安全隐患。所以密码是需要有效期的。Token也当然是需要有效期的。根据系统的安全需要,选择合适的有效期时间长度。
正常情况下:当用户的Token失效之后,需要用户重新登录,获取新的Token信息,该Token在有效期内是可以不需要重复验证用户名密码的。但是当用户正在使用应用程序的时候,有效期到了,用户被强制退出,要求重新登录系统,这样是很不友好的。比如用户正在录入表单,马上填写完成了,被强制退出,用户会疯掉的。
所以有的时候需要用户去自动刷新(推迟)Token的过期时间,将有效期时间变得更长。比如,用户在每次向服务器发送请求的时候,都去刷新Token的过期时间,Session 就是采用这种策略来保持用户登录状态的。当每次请求服务端的时候都去刷新Token的时候,存在一个问题,就是当用户量很大的时候,每次用户请求服务端的时候都去刷新Token的过期时间,这样的的代价是非常大的,如,把Token持久化到数据库了,如果每秒有很多请求,那么每秒就要去修改保存Token信息表很多次,如果请求量很大,数据库会受不了的。有时为了提升Token的状态更新时的效率,会把Token信息保存到缓存或内存中,比如:可以把Token信息保存到Redis中。
上面的方案,把Token信息保存到缓存或者内存的时候,当访问量很高的时候,还是对服务器的效率产生影响的。
但是如果我们刷新Token信息的过期时间不是那么频繁,当Token快要过期的时候,在进行刷新,这样就会避免频繁的读写操作。这时我们可以使用Refresh Token,它可以很好的避免频繁的读写操作。这个方案中服务端不需要刷新Token的过期时间,一旦Token过期或者快过期了,就反馈给前端,前端使用Refresh Token申请一个全新的Token继续使用。这时服务端只需要在客户端请求更新Token的时候对Refresh Token的有效期进行一次检查,大大减少了更新有效期的操作,也避免了频繁读写操作。