• 【项目小tips】登录状态存储


    前言

    本系列主要整理前端项目中需要掌握的知识点。本节介绍登录状态存储。


    一、为什么要存储登录状态

    HTTP是一种无状态的协议,这会导致每次请求都是独立的,服务器没办法判断两次请求是否来自同一个用户,进而也没办法判断本次用户是否需要重新出入用户名和密码,此时就需要存储登录状态,来方便同一个用户登录时不需要重新输入账号密码。

    二、Cookie+SessionID存储登录状态

    1. Cookie是什么?

    在这里插入图片描述
    Cookie是服务器端发送给客户端的一段特殊信息,这些信息以文本的方式存储在客户端,客户端每次向服务器发起请求时都会携带上Cookie,服务端通过Cookie获取客户端传递过来的信息。但是如果把用户信息都存储在Cookie中,一旦Cookie被获取到,那么用户的信息就会暴露,因此这这是非常不安全的,又引入了SessionID

    2. Session是什么?

    在这里插入图片描述
    首先使用用户名和密码发送给服务器,服务器核对后发现密码是对的,身份认证成功,于是在服务器这边创建一个SessionID和会话结束时间,SessionID通常是一串没有规律的字符串。创建完成后,服务器要把SessionID和会话结束时间发送给浏览器,这里就用到了Cookie,并且把SessionID加入到Cookie里,再把会话结束时间对应设置为这个Cookie的有效期,浏览器拿到Cookie后进行保存,这时,浏览器保存的并不是用户名和密码,而是SessionID。后续发请求时,都会自动发送Cookie到相应服务器那里,也就是说,浏览器的下次访问、下下次访问都会自动发送这个SessionID给服务器,直到Cookie的有效期失效之后,浏览器一般就会自行删除这个Cookie,这时就是会话结束了。在Cookie失效之后,用户就得重新输入用户名密码了。

    3. Cookie+SessionID的登录流程

    用户首次登录时:
    在这里插入图片描述

    1. 用户访问a.com/pageA,并输入密码登录;
    2. 服务器验证账号密码无误后,会创建sessionID并保存起来
    3. 服务器端响应HTTP请求,并通过Set-Cookie将SessionID写入Cookie中。

    后续的登录就可以直接使用Cookie进行身份验证了:
    在这里插入图片描述

    1. 用户访问a.com/pageA页面时,会携带上第一次登录时写入的Cookie
    2. 服务器端对比Cookie中的SessionID和保存在服务器中的SessionID是否一致
    3. 如果一致,则身份验证成功。

    4. Cookie+SessionID存在的问题

    • 由于SessionID存放在服务器中,一台服务器会对接多台客户端,服务器端存放大量的SessionID,导致服务器压力过大;
    • 如果采用分布式服务器,各台服务器之间同步SessionID增加了维护的成本。

    三、Token+localStorage存储登录状态

    Token是服务端生成的一串字符串,作为客户端请求的一个令牌。当第一次登录后,服务器会生成一个Token并返回给客户端,客户端后续访问时,只需要带上这个Token就可以完成身份认证。
    在这里插入图片描述

    1. Token实现登录的流程

    用户首次登录时:
    在这里插入图片描述

    1. 用户输入账号密码,并点击登录;
    2. 服务器验证账号密码无误,创建Token;
    3. 服务器将Token返回给客户端,由客户端自由保存;

    后续页面访问时:
    在这里插入图片描述

    1. 用户访问a.com/pageA时,带上第一次登录时获取的Token。
    2. 服务器端验证Token,有效则身份验证成功。

    2. Token的生成方式

    最常用的Token生成方式是使用JWT(Json Web Token),JWT的本质就是一个字符串,它将用户的信息保存到一个JSON字符串中,然后编码得到一个Token,并且这个Token带有签名信息,在接受后可以校验是否篡改。

    JWT结构: JWT由Header(头部)、PayLoad(有效载荷)、Signature(签名)组成。

    • Header中存储着一些描述信息;
    • PayLoad中存储着用户的信息,还有token的有效期等;
    • Signature确保数据不被篡改。

    JWT的认证流程如下:

    1. 首先,前端通过表单将自己的用户名和密码发送到后端的接口,这个过程一般是POST请求,建议使用HTTPS进行传输,防止敏感信息被篡改。
    2. 后端核对用户名和密码成功后,将包含用户信息的数据作为JWTPayload,将其与JWT Header分别进行Base64编码拼接后签名,形成一个JWT Token,形成的JWT Token就是一个如同aaa.bbb.ccc的字符串
    3. 后端将JWT Token字符串作为登录成功的结果返回给前端。前端可以将返回的结果保存在浏览器中,退出登录时删除保存的JWT Token即可
    4. 前端在每次请求时将JWT Token放入HTTP请求头中的Authorization属性中(解决XSSCSRF问题)
    5. 后端检查前端传过来的JWT Token,验证其有效性。将headerbase64解码,得到JWT使用什么算法进行签名的,然后在用这个算法,对headerpayload进行一次签名,与token本身的签名进行对比,判断第三个部分的字符串是否一致,如果不同,则认为这个token是被篡改过的。
    6. 验证通过后,后端解析出JWT Token中包含的用户信息,进行其他逻辑操作(一般是根据用户信息得到权限等),返回结果。

    为什么使用Token不会导致服务端压力过大?
    原因就是Token的验证方式,服务端检查token的方式是将header用base64解码,得到JWT使用什么算法进行签名,然后再用这个算法对header和payload进行一次签名,与token本身的签名进行对比,判断三个部分的字符串是否一致,如果不同,就是验证失败。所以服务端存储的Token信息只是一个验证方法,且无论有多少个客户端,都是用同一种方式进行验证的。

    3. 使用Token验证登录的优缺点

    优点:

    • Token存放在客户端本地,减轻了对服务端的压力;
    • 可以放在请求头中携带,防止CSRF攻击;(不再依赖cookie)
    • Token在跨域后不存在信息丢失的问题。(cookie是无法跨域的,而token放在了请求头中,所以跨域不会丢失)

    缺点:

    • Token放在请求头中也有可能遭受到劫持,所以要全链路使用HTTPS进行传输;
    • Token如果有效期设置太长容易产生安全问题,因为Token可以通过暴力穷举法破解;
    • Token一旦下发,服务端想要收回用户的权限就变得艰难;
    • Token需要签名,性能稍差;
    • 如果服务器不慎将Signature泄露,客户端可能会自行签发Token、中间人也可以肆意篡改Token。

    4. Token过期了怎么处理

    • 当登录用户的Token过期了,会出现401状态码。当然当未登录的用户做一些需要权限才能做的操作,服务端也会响应401。
    • 当用户登录成功后,服务端会返回token两个值,一个是refresh_token,一个是token。其中,refresh_token的有效期是比较长的,如果token过期了,可以再用它发请求,再次获得一个有效的token。实现的是Token续签。
    • refresh_token的具体解释: 服务端不需要刷新 Token 的过期时间,一旦 Token 过期,就反馈给前端,前端使用 Refresh Token 申请一个全新 Token 继续使用。这种方案中,服务端只需要在客户端请求更新 Token 的时候对 Refresh Token 的有效性进行一次检查,大大减少了更新有效期的操作,也就避免了频繁读写。当然 Refresh Token 也是有有效期的,但是这个有效期就可以长一点了,比如,以天为单位的时间。refresh token,也是加密字符串,并且和token是相关联的。相比获取各种资源的token,refresh token的作用仅仅是获取新的token,因此其作用和安全性要求都大为降低,所以其过期时间也可以设置得长一些。
      在这里插入图片描述
  • 相关阅读:
    李沐——论文阅读——VIT(VIsionTransformer)
    LeetCode 视频演示:0654. 最大二叉树(视频做了近2h~_~)
    genius-storage使用文档,一个浏览器缓存工具
    国产API管理神器Eolink也太强了吧
    基于邻接矩阵的深度优先算法和广度优先算法
    开源免费的流程设计器如何选型
    Transformers.js v2.6 现已发布
    php时间选择器插件与安全过滤参数发生空格冲突
    20天深度复习JavaSE的详细笔记(十八)——网络编程
    前端三剑客第一剑—Html基础标签讲解
  • 原文地址:https://blog.csdn.net/weixin_44337386/article/details/126719622