关键词
登录认证、登录态、session、token、refreshToken、cookie
为什么需要登录认证?
web网页最初只是起浏览数据的作用,所有人访问网站都是为了去看同一份数据。但随着互联网行业的兴起,购物网站、论坛网站层出不穷,web需要去记录哪些人登录过网站,这些人的专属数据是什么,且不能互相影响。
比如我在某宝上把一件衣服加入了购物车,但是第二天起床发现我的购物车被其他人清空了,这样就很离谱了。
所以就需要一个登录过程,用户输入账号、密码来证明“你就是你” ,那么服务端就可以区分不同的用户了。
如何维持登录态?
但是**http是无状态协议,每次客户端和服务端完成会话即用户关闭网页之后,服务端都不会保存任何会话信息**,所以每次都要重新输入账号密码重新登录一次,这样对用户来讲体验性很不好。
所以此时就需要一个标识符来让服务端知道,这个人是上次登录过的,不用再输一遍账号密码验证了。
那么我们可以在首次会话时,在服务端生成一个随机字符串session_id存入库中,并且将它传给客户端,客户端下次发起会话的时候再带过来,和服务端存储的session_id就说明此人上次访问过,不用走登录了。
如何降低服务端压力?
使用session_id的确可以维持登录态,优化客户体验,但如果在网站用户量很大的情况下,例如网站总用户达千万,那岂不是要同时储存千万个session_id?这对服务端来讲可是一笔不小的开销。
既然服务端存不了,那能否把标识符存到客户端,服务端只是做校验即可。
乍一看,流程和上面的session_id差不多,只是多了个服务端校验的过程,其实上面也是有校验,但上面的校验只是去库中找有不有sesson_id而已,而我们这里要转变思路。
首次登录:
服务端存有一套加密算法和秘钥,首次登录时,会将该用户拿到的数据和秘钥结合加密算法生成签名,再将数据和签名结合成token发给客户端
客户端下次登录时会带上
token,服务端解析出token中的数据,再将数据和秘钥结合加密算法生成签名,最后将生成的签名和token中的签名作对比,一样的话则代表该用户曾经登录过,不用再次登录了
如何存储token?
既然说到token是放到客户端的,我们可以使用cookie来进行存储。
cookie 是服务器发送到用户浏览器并保存在本地的一小块数据,它会在浏览器下次向同一服务器再发起请求时被携带并发送到服务器上。
并且每个 cookie 都会绑定单一的域名,无法在别的域名下获取使用。
| 属性 | 说明 |
|---|---|
| domain | 指定 cookie 所属域名 |
| path | 指定 cookie 在哪个路径(路由)下生效,默认是 '/' |
| expires | 过期时间:天 |
如何刷新token?
refreshToken
refreshToken的最大作用其实就是当accessToken一周时间失效时,拿refreshToken去换取最新的accessToken和refreshToken,所以只要当用户在一个月内有过登录,就永远不会重新走输账号、密码的显式登录(除了用户自己主动退出登录或清空token)
而如果用户在一个月内从未登录过,refreshToken就失效了,那肯定会走显示登录
其它问题
顾问端、医生端axios封装差异问题,见代码