登陆方案学习笔记

...

Posted by 呆贝斯 on December 15, 2021

主流Web应用是基于HTTP协议的,而HTTP协议是无状态的,就是服务器不知道谁发送这个HTTP请求,无法识别用户身份。

登录态就是服务器用来区分用户身份的,同时对用户进行记录的技术方案。怎么实现用户的登录态呢?常见的实现流程如下: login

  1. 客户端用户输入登录凭据(如账户和密码),发送登录请求。
  2. 服务端校验用户是否合法(如认证和鉴权),合法后返回登录态,不合法返回第1步。
  3. 合法后携带登录态访问用户数据。

HTTP基本验证

HTTP基本认证是HTTP协议本身提供了一种服务端对客户端进行用户身份验证的方法。流程如下: login

  1. 客户端向服务端请求需要登录态的数据
  2. 服务端向客户端返回401状态码,要求客户端验证
  3. 客户端根据返回的 WWW-Authenticate: Basic realm=”qq.com”,弹出用户名和密码输入框要求用户进行验证。
  4. 用户输入用户名和密码后,客户端将用户名及密码以 Base64 格式发送给服务端。
  5. 服务端验证通过后返回用户数据。

优点:兼容性好,主流浏览器都支持

缺点:不安全,账号密码是Base64编码,很容易解码。无法主动注销,除非关闭标签或浏览器。

Cookie和Session认证

什么是Cookie?

Cookie是客户端请求服务端时,由服务端创建并由客户端存储和管理的小文本文件。具体流程如下:

  1. 客户端首次发起请求。
  2. 服务端通过HTTP响应头里Set-Cookie字段返回Cookie信息。
  3. 客户端再发起请求时会通过HTTP请求头里Cookie字段携带Cookie信息。

什么是Session?

Session是客户端请求服务端时服务端会为这次请求创建一个数据结构,这个结构可以通过内存、文件、数据库等方式保存。 具体流程如下:

  1. 客户端首次发起请求。
  2. 服务端收到请求并自动为该客户端创建特定的Session并返回SessionID,用来标识该客户端。
  3. 客户端通过服务端响应获取SessionID,并在后续请求携带SessionID。
  4. 服务端根据收到的SessionID,在服务端找对应的Session,进而获取到客户端信息。

Cookie和Session认证流程

cookie_session

  1. 客户端向服务端发送认证信息(例如账号密码)
  2. 服务端根据客户端提供的认证信息执行验证逻辑,如果验证成功则生成Session并保存,同时通过响应头Set-Cookie字段返回对应的SessionID
  3. 客户端再次请求并在Cookie里携带SessionID。
  4. 服务端根据SessionID查找对应的Session,并根据业务逻辑返回相应的数据。

Cookie和Session认证优缺点

优点:Cookie由客户端管理,支持设定有效期、安全加密、防篡改、请求路径等属性。Session由服务端管理, 支持有效期,可以存储各类数据。

缺点:Cookie只能存储字符串,有大小和数量限制,对移动APP端支持不好,同时有跨域限制(主域不同)。Session存储在服务端, 对服务端有性能开销,客户端量太大会影响性能。如果集中存储(如存储在Redis),会带来额外的部署维护成本。

Token认证

Token又叫令牌,是服务端生成用来验证客户端身份的凭证,客户端每次请求都携带Token。Token一般由以下数据组成:

  • uid(用户唯一的身份标识)
  • time(当前时间的时间戳)
  • sign(签名,由token的前几位+盐用哈希算法压缩成一定长的十六进制字符串)

Token认证流程

token_auth

  1. 客户端向服务端发送认证信息(例如账号密码)
  2. 服务端根据客户端提供的认证信息执行验证逻辑(如查询数据库),如果验证成功则生成Token并返回。
  3. 客户端存储(可以存在Cookie、LocalStorage或本地缓存里)收到的Token,再次请求时携带Token(可以通过HTTP请求头Authorization字段)。
  4. 服务端校验Token(如查询数据库),并根据业务逻辑返回相应的数据。

Token认证优缺点

优点:客户端可以用Cookie、LocalStorage等存储,服务端不需要存储。安全性高(有签名校验)。支持移动APP端。支持跨域。

缺点:占用额外传输宽带,因为Token比较大,可能会消耗一定的流量。每次签名校验会消耗服务端性能。有效期短(避免被盗用)。

Refresh Token

点击跳转

JWT

点击跳转

单点登录认证

上面说的都是同一个域名(或同一主域)下,通过Cookie或Token携带凭证实现登录态管理。但是如果有很多域名, 如何实现用户在一个域名下登录后,访问另一个域名也能自动登录呢?这就是单点登录问题(Single Sign On)

要实现SSO,需要有一个CAS(Central Authentication Service)中央授权服务(假设域名为cas.com) 来提供统一的登录功能。

单点登录认证流程

假如现在有域名http://abc.com和http://123.com要实现互相自动登录。流程如下:

  1. 先访问http://abc.com sso_1
    1. 客户端访问http://abc.com
    2. http://abc.com发现没有登录(http://abc.com域下没有Session或Session失效),302跳转到http://cas.com并携带http://abc.com的回调地址(登录成功跳转回来的页面链接)。
    3. http://cas.com发现没有登录(http://cas.com域下没有Session或Session失效),302跳转到http://cas.com登录页面并携带http://abc.com的回调地址。
    4. 客户端携带http://abc.com回调地址访问http://cas.com。
    5. 客户端向http://cas.com发送认证信息(例如账号密码)。
    6. http://cas.com登录成功并生成http://cas.com域下的Session,同时生成一个Token,根据回调地址携带此Token重定向到http://abc.com。
    7. 客户端携带Token访问http://abc.com。
    8. http://abc.com访问http://cas.com验证Token的有效性,验证成功并生成http://abc.com域下的Session,完成登录。
  2. 再访问http://123.com sso_2
    1. 客户端访问http://123.com
    2. http://123.com校验失败,需要登录(http://123.com域下没有Session或Session失效),302重定向到http://cas.com,并携带http://123.com回调地址。
    3. 客户端携带http://123.com回调地址访问http://cas.com。
    4. http://cas.com根据http://cas.com下的Session(访问http://abc.com时生成的)发现用户已登录,生成Token后302重定向到http://123.com。
    5. http://123.com访问http://cas.com验证Token的有效性,验证成功并生成http://123.com域下的Session,完成登录。

总结

  • HTTP基本认证:一般用于对安全要求不高或内部系统用户量极少的场景,实际应用不多。
  • Cookie和Session认证:一般应用于浏览器环境。
  • Token认证:除了浏览器环境外,还可以应用于移动端APP、小程序、PC端软件等非浏览器环境。
  • 单点登录认证:应用于大型站群系统或企业内不同业务系统间互通。