一文搞懂前后端常见登录态方案

正文开始之前,我们先要了解一个概念,就是什么是 登录态
。
主流Web应用比如浏览器是基于http协议的,而http协议是 无状态
的。什么是 无状态
?就是服务器不知道是谁发送了这个http请求,无法识别区分用户身份。
所以登录态就是服务端用来区分用户身份,同时对用户进行记录的技术方案。
那怎么实现用户的登录态呢?常见的实现流程如下:
- 客户端用户输入登录凭据(如账户和密码),发送登录请求。
- 服务端校验用户是否合法(如认证和鉴权),合法后返回登录态,不合法返回第1步。
- 合法后携带登录态访问用户数据。
流程有了,如何实现呢?
常见的方案有HTTP基本认证、Cookie和Session认证、Token认证、单点登录认证等,下面一一介绍。
1. HTTP基本认证
HTTP基本认证是HTTP协议本身提供了一种服务端对客户端进行用户身份验证的方法。 流程如下:
sequenceDiagram
autonumber
客户端->>服务端:Get / HTTP/1.1 Host:www.qq.com
服务端->>客户端:HTTP/1.1 401 Unauthorised WWW-Authenticate: Basic realm="qq.com"
客户端->>客户端:弹出登录窗口
客户端->>服务端:Get / HTTP/1.1 Host:www.qq.com Authorization: Basic xxxxxx
服务端->>客户端:验证成功,返回用户数据
- 客户端向服务端请求需要登录态的数据
- 服务端向客户端返回401状态码,要求客户端验证
- 客户端根据返回的
WWW-Authenticate: Basic realm="qq.com"
,弹出用户名和密码输入框要求用户进行验证。 - 用户输入用户名和密码后,客户端将用户名及密码以
Base64
格式发送给服务端。 - 服务端验证通过后返回用户数据。
这是一种比较简单的验证用户身份的方式,甚至不需要写代码,只要后端服务器配置一下即可。
优点:兼容性好,主流浏览器都支持
缺点:
- 不安全,账号密码是Base64编码,很容易解码。
- 无法主动注销,除非关闭标签或浏览器。
2. Cookie和Session认证
先了解两个概念,Cookie和Session是什么呢? 上面说到HTTP是一种无状态协议
,而Cookie和Session可以弥补 HTTP 的无状态特性。
2.1 什么是Cookie
Cookie是客户端请求服务端时,由服务端创建并由客户端存储和管理的小文本文件。具体流程如下:
- 客户端首次发起请求。
- 服务端通过HTTP响应头里Set-Cookie字段返回Cookie信息。
- 客户端再发起请求时会通过HTTP请求头里Cookie字段携带Cookie信息。
2.2 什么是Session
Session是客户端请求服务端时服务端会为这次请求创建一个数据结构,这个结构可以通过内存、文件、数据库等方式保存。具体流程如下:
- 客户端首次发起请求。
- 服务端收到请求并自动为该客户端创建特定的Session并返回SessionID,用来标识该客户端。
- 客户端通过服务端响应获取SessionID,并在后续请求携带SessionID。
- 服务端根据收到的SessionID,在服务端找对应的Session,进而获取到客户端信息。
2.3 Cookie和Session认证流程
- 客户端向服务端发送认证信息(例如账号密码)
- 服务端根据客户端提供的认证信息执行验证逻辑,如果验证成功则生成Session并保存,同时通过响应头Set-Cookie字段返回对应的SessionID
- 客户端再次请求并在Cookie里携带SessionID。
- 服务端根据SessionID查找对应的Session,并根据业务逻辑返回相应的数据。
2.4 Cookie和Session认证优点
- Cookie由客户端管理,支持设定有效期、安全加密、防篡改、请求路径等属性。
- Session由服务端管理,支持有效期,可以存储各类数据。
2.4 Cookie和Session认证缺点
- Cookie只能存储字符串,有大小和数量限制,对移动APP端支持不好,同时有跨域限制(主域不同)。
- Session存储在服务端,对服务端有性能开销,客户端量太大会影响性能。如果集中存储(如存储在Redis),会带来额外的部署维护成本。
3. Token认证
Token又叫令牌,是服务端生成用来验证客户端身份的凭证,客户端每次请求都携带Token。 Token一般由以下数据组成:
uid(用户唯一的身份标识)
time(当前时间的时间戳)
sign(签名,由token的前几位+盐用哈希算法压缩成一定长的十六进制字符串)
3.1 Token认证流程
- 客户端向服务端发送认证信息(例如账号密码)
- 服务端根据客户端提供的认证信息执行验证逻辑(如查询数据库),如果验证成功则生成Token并返回。
- 客户端存储(可以存在Cookie、LocalStorage或本地缓存里)收到的Token,再次请求时携带Token(可以通过HTTP请求头Authorization字段)。
- 服务端校验Token(如查询数据库),并根据业务逻辑返回相应的数据。
3.2 Token认证优点
- 客户端可以用Cookie、LocalStorage等存储,服务端不需要存储。
- 安全性高(有签名校验)。
- 支持移动APP端。
- 支持跨域。
3.3 Token认证缺点
- 占用额外传输宽带,因为Token比较大,可能会消耗一定的流量。
- 每次签名校验会消耗服务端性能。
- 有效期短(避免被盗用)。
3.4 Refresh Token
3.3里说到为了避免被盗用Token一般有效期比较短。但是有效期太短会造成客户端不断重新登录,体验太差。有没有什么办法可以解决这个问题呢?
那就是再来一个Token,一个专门生成Token的Token,称为 Refresh Token
。
流程如下:
- 客户端向服务端发送认证信息(例如账号密码)
- 服务端根据客户端提供的认证信息执行验证逻辑(如查询数据库),如果验证成功则生成Token和Refresh Token并返回。
- 客户端存储(可以存在Cookie、LocalStorage或本地缓存里)收到的Token和Refresh Token,再次请求时携带Token(可以通过HTTP请求头Authorization字段)。
- 服务端校验Token(如查询数据库),并根据业务逻辑返回相应的数据。
- 服务端发现Token过期了,拒绝了请求。
- 客户端重新请求并携带Refresh Token。
- 服务端校验Refresh Token并返回新Token和新Refresh Token。
- 客户端再次请求并携带新Token。
3.5 JWT
3.3、3.4里服务端校验客户端发过来的Token是否有效时,可能会查询数据库来验证。如果每次请求都要查询数据库,可能会带来额外性能消耗。
那这个有没有办法优化呢?
答案是有的,那就是JWT(JSON Web Token
)。JWT
是 Auth0
提出的通过 对JSON进行加密签名
来实现授权验证的方案。
JWT也是一种Token,由三部分组成: Header头部
、 Payload负载
和 Signature签名
。它是一个很长的字符串,中间用点( .
)分隔成三个部分,列如 :
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
Header头部:
{ "alg": "Hash算法(HMAC、SHA256或RSA)", "typ": "Token的类型(JWT)" }
Payload负载:
{ "iss": "签发人(issuer)", "exp": "过期时间(expiration time)", "sub": "主题(subject)", "aud": "受众(audience)", "nbf": "生效时间(not before)", "iat": "签发时间(issued at)", "jti": "编号(JWT ID)", "uid": "自定义字段(可以存储用户ID等)", }
Signature 签名:
HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret //设置的密钥 )
JWT的流程和Token的基本一样,因为已经携带了客户端信息(如用户ID等),所以服务端校验Token时不需要查询数据库了。
4. 单点登录认证
上面说的都是同一个域名(或同一主域)下,通过Cookie或Token携带凭证实现登录态管理。但是如果有很多域名,如何实现用户在一个域名下登录后,访问另一个域名也能自动登录呢?
这就是单点登录问题(Single Sign On
)
要实现SSO,需要有一个CAS(Central Authentication Service)
中央授权服务(假设域名为cas.com)来提供统一的登录功能。
假如现在有域名http://abc.com和http://123.com要实现互相自动登录。流程如下:
- 客户端访问http://abc.com
- http://abc.com发现没有登录(http://abc.com域下没有Session或Session失效),302跳转到http://cas.com并携带http://abc.com的回调地址(登录成功跳转回来的页面链接)。
- http://cas.com发现没有登录(http://cas.com域下没有Session或Session失效),302跳转到http://cas.com登录页面并携带http://abc.com的回调地址。
- 客户端携带http://abc.com回调地址访问http://cas.com。
- 客户端向http://cas.com发送认证信息(例如账号密码)。
- http://cas.com登录成功并生成http://cas.com域下的Session,同时生成一个Token,根据回调地址携带此Token重定向到http://abc.com。
- 客户端携带Token访问http://abc.com。
- http://abc.com访问http://cas.com验证Token的有效性,验证成功并生成http://abc.com域下的Session,完成登录。
- 客户端访问http://123.com
- http://123.com校验失败,需要登录(http://123.com域下没有Session或Session失效),302重定向到http://cas.com,并携带http://123.com回调地址。
- 客户端携带http://123.com回调地址访问http://cas.com。
- http://cas.com根据http://cas.com下的Session(访问http://abc.com时生成的)发现用户已登录,生成Token后302重定向到http://123.com。
- http://123.com访问http://cas.com验证Token的有效性,验证成功并生成http://123.com域下的Session,完成登录。
总结:
- HTTP基本认证:一般用于对安全要求不高或内部系统用户量极少的场景,实际应用不多。
- Cookie和Session认证:一般应用于浏览器环境。
- Token认证:除了浏览器环境外,还可以应用于移动端APP、小程序、PC端软件等非浏览器环境。
- 单点登录认证:应用于大型站群系统或企业内不同业务系统间互通。
以上总结4种了常见的登录方案,还有OAuth2.0、扫码登录等方式,后续还会继续更新,敬请期待。。。
作者:yanweiyao
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
2018-12-20 各常用分类算法的优缺点总结:DT/ANN/KNN/SVM/GA/Bayes/Adaboosting/Rocchio
2013-12-20 人生就像公交车
2010-12-20 相由心生