沉梦听雨的编程指南 沉梦听雨的编程指南
首页
  • 基础篇
  • 集合篇
  • 并发篇
  • JVM
  • 新特性
  • 计算机网络
  • 操作系统
  • 数据结构与算法
  • 基础篇
  • MySql
  • Redis
  • 达梦数据库
  • Spring
  • SpringBoot
  • Mybatis
  • Shiro
  • 设计须知
  • UML画图
  • 权限校验
  • 设计模式
  • API网关
  • RPC
  • 消息队列
  • SpringCloud
  • 分布式事务
  • 云存储
  • 搜索引擎
  • 多媒体框架
  • 虚拟机
  • 开发工具篇
  • 工具库篇
  • 开发技巧篇
  • 工具类系列
  • 随笔
  • 前端环境搭建
  • HTML与CSS
  • JS学习
  • Vue3入门
  • Vue3进阶
  • 黑马Vue3
  • 脚手架搭建
  • 瑞吉外卖
  • 黑马点评
  • vue-blog
  • 沉梦接口开放平台
  • 用户中心
  • 聚合搜索平台
  • 仿12306项目
  • 壁纸小程序项目
  • RuoYi-Vue
  • 博客搭建
  • 网站收藏箱
  • 断墨寻径摘录
  • 费曼学习法
Github (opens new window)

沉梦听雨

时间是最好的浸渍剂,而沉淀是最好的提纯器🚀
首页
  • 基础篇
  • 集合篇
  • 并发篇
  • JVM
  • 新特性
  • 计算机网络
  • 操作系统
  • 数据结构与算法
  • 基础篇
  • MySql
  • Redis
  • 达梦数据库
  • Spring
  • SpringBoot
  • Mybatis
  • Shiro
  • 设计须知
  • UML画图
  • 权限校验
  • 设计模式
  • API网关
  • RPC
  • 消息队列
  • SpringCloud
  • 分布式事务
  • 云存储
  • 搜索引擎
  • 多媒体框架
  • 虚拟机
  • 开发工具篇
  • 工具库篇
  • 开发技巧篇
  • 工具类系列
  • 随笔
  • 前端环境搭建
  • HTML与CSS
  • JS学习
  • Vue3入门
  • Vue3进阶
  • 黑马Vue3
  • 脚手架搭建
  • 瑞吉外卖
  • 黑马点评
  • vue-blog
  • 沉梦接口开放平台
  • 用户中心
  • 聚合搜索平台
  • 仿12306项目
  • 壁纸小程序项目
  • RuoYi-Vue
  • 博客搭建
  • 网站收藏箱
  • 断墨寻径摘录
  • 费曼学习法
Github (opens new window)
  • 设计须知

  • UML画图

  • 权限校验

    • 什么是RBAC权限模型?
    • 那些鉴权相关的知识
      • 认证、授权、凭证
        • 什么是认证(Authentication)
        • 什么是授权(Authorization)
        • 什么是凭证(Credentials)
      • 鉴权机制
        • 一、什么是 Cookie
        • 二、什么是 Session
        • Cookie 和 Session 的区别
        • 三、什么是 Token(令牌)
        • Acesss Token
        • Refresh Token
        • Token 和 Session 的区别
        • 四、什么是 JWT
        • Token 和 JWT 的区别
      • 常见的前后端鉴权方式
      • 常见的加密算法
      • 常见问题
        • 使用 Cookie 时需要考虑的问题
        • 使用 Session 时需要考虑的问题
        • 使用 Token 时需要考虑的问题
        • 使用 JWT 时需要考虑的问题
        • 使用加密算法时需要考虑的问题
        • 只要关闭浏览器 ,session 真的就消失了?
      • 学习参考
    • 深入了解 Bearer 模式
    • JWT 基础小结
    • token令牌问题
    • 安全框架SpringSecurity入门
    • SpringSecurity+OAuth2入门
  • 设计模式

  • 系统设计
  • 权限校验
沉梦听雨
2025-01-03
目录

那些鉴权相关的知识

# 那些鉴权相关的知识

# 认证、授权、凭证

# 什么是认证(Authentication)

  1. 通俗地讲就是验证当前用户的身份
  2. 互联网中的认证:
    • 用户名密码登录
    • 邮箱发送登录链接
    • 手机号接收验证码
    • 只要你能收到邮箱/验证码,就默认你是账号的主人

# 什么是授权(Authorization)

  1. 用户授予第三方应用访问该用户某些资源的权限

    • 你在安装手机应用的时候,APP 会询问是否允许授予权限(访问相册、地理位置等权限)

    • 你在访问微信小程序时,当登录时,小程序会询问是否允许授予权限(获取昵称、头像、地区、性别等个人信息)

  2. 常见授权方式:

    • Cookie。
    • Session。
    • Token。
    • OAuth。

# 什么是凭证(Credentials)

  1. 凭证用于认证后,可生成会话或令牌,用于后续授权。
  2. 凭证是用户或系统用来证明自己身份的信息。是在身份验证成功后,用来表明身份和授权的标识。
    • Session ID:通过用户名和密码登录后生成的。
    • Token 或 JWT:验证用户名和密码后发放的令牌。
  3. 是一种 **媒介(证书)**用来标记访问者的身份
    • 在战国时期,商鞅变法,发明了照身帖。照身帖由官府发放,是一块打磨光滑细密的竹板,上面刻有持有人的头像和籍贯信息。国人必须持有,如若没有就被认为是黑户,或者间谍之类的。
    • 在现实生活中,每个人都会有一张专属的居民身份证,是用于证明持有人身份的一种法定证件。通过身份证,我们可以办理手机卡/银行卡/个人贷款/交通出行等等,这就是认证的凭证。
    • 在互联网应用中,一般网站(如掘金)会有两种模式,游客模式和登录模式。游客模式下,可以正常浏览网站上面的文章,一旦想要点赞/收藏/分享文章,就需要登录或者注册账号。当用户登录成功后,服务器会给该用户使用的浏览器颁发一个令牌(token),这个令牌用来表明你的身份,每次浏览器发送请求时会带上这个令牌,就可以使用游客模式下无法使用的功能。

# 鉴权机制

# 一、什么是 Cookie

HTTP 是无状态的协议(对于事务处理没有记忆能力,每次客户端和服务端会话完成时,服务端不会保存任何会话信息):

  • 每个请求都是完全独立的,服务端无法确认当前访问者的身份信息,无法分辨上一次的请求发送者和这一次的发送者是不是同一个人。
  • 所以服务器与浏览器为了进行会话跟踪(知道是谁在访问我),就必须主动的去维护一个状态,这个状态用于告知服务端前后两个请求是否来自同一浏览器。
  • 而这个状态需要通过 cookie 或者 session 去实现。
  1. Cookie 是存储在浏览器中的小型文本文件,由服务器发送并存储在用户的设备上。(即存储在客户端)

    • 保存在本地的一小块数据

    • 用于在客户端和服务器之间共享数据。

  2. 特点:

    • 每次请求时会自动发送给服务器。
    • 可以设置过期时间。
    • 支持跨页面共享。
    • cookie 是不可跨域的: 每个 cookie 都会绑定单一的域名,无法在别的域名下获取使用,一级域名和二级域名之间是允许共享使用的(靠的是 domain)
  3. 常见用途:

    • 保存用户登录状态。
    • 存储偏好设置(如语言、主题)。
    • 跟踪用户行为(如广告投放)。
  4. cookie 重要的属性:

    • 属性 说明
      name=value 键值对,设置 Cookie 的名称及相对应的值,都必须是字符串类型 - 如果值为 Unicode 字符,需要为字符编码。 - 如果值为二进制数据,则需要使用 BASE64 编码。
      domain 指定 cookie 所属域名,默认是当前域名
      path 指定 cookie 在哪个路径(路由)下生效,默认是 '/'。 如果设置为 /abc,则只有 /abc 下的路由可以访问到该 cookie,如:/abc/read。
      maxAge cookie 失效的时间,单位秒。(1)如果为整数,则该 cookie 在 maxAge 秒后失效。(2)如果为负数,该 cookie 为临时 cookie,关闭浏览器即失效,浏览器也不会以任何形式保存该 cookie 。(3)如果为 0,表示删除该 cookie 。 默认为 -1。比 expires 好用。
      expires 过期时间,在设置的某个时间点后该 cookie 就会失效。一般浏览器的 cookie 都是默认储存的,当关闭浏览器结束这个会话的时候,这个 cookie 也就会被删除
      secure 该 cookie 是否仅被使用安全协议传输。安全协议有 HTTPS,SSL等,在网络上传输数据之前先将数据加密。 - 默认为 false。 - 当 secure 值为 true 时,cookie 在 HTTP 中是无效,在 HTTPS 中才有效。
      httpOnly 如果给某个 cookie 设置了 httpOnly 属性,则无法通过 JS 脚本 读取到该 cookie 的信息,但还是能通过 Application 中手动修改 cookie,所以只是在一定程度上可以防止 XSS 攻击,不是绝对的安全

# 二、什么是 Session

SessionID 是连接 Cookie 和 Session 的一道桥梁,大部分系统也是根据此原理来验证用户登录状态。

  1. Session 是另一种记录服务器和客户端会话状态的机制,用于记录用户的交互状态。
    • 用户首次访问时,服务器创建一个 Session 对象,并生成一个唯一的 Session ID 返回给客户端(浏览器)。
    • Session ID 通常通过 Cookie 或 URL 参数传递到客户端。
    • session 是基于 cookie 实现的,session 存储在服务器端,SessionID 会被存储到客户端的 cookie 中
    • 第二次请求时,携带 cookie 中的 SessionID,便于服务器判断 SessionID 属于哪个用户,并执行后续操作(为了进行会话跟踪 -- 知道是谁在访问我)
  2. 特点:
    • 数据存储在服务器端,更安全。
    • 通常与用户的会话周期绑定。
    • 对服务器资源有一定消耗。
  3. 常见用途:
    • 记录用户登录状态。
    • 存储临时数据(购物车、浏览记录)。

验证流程:

image

# Cookie 和 Session 的区别

属性 Cookie Session
存储位置 客户端 服务器
安全性 较低,数据容易被篡改 较高,数据存储在服务器端
存取值的类型不同 只支持存字符串数据 可以存任意数据类型
生命周期 可设置过期时间,支持持久化 会话结束或超时后失效
存储容量 单个 Cookie 保存的数据不能超过 4KB 取决于服务器资源

# 三、什么是 Token(令牌)

# Acesss Token

  1. Acesss Token 是访问受保护资源(资源接口 API)的凭证。
    • 由服务器生成并返回给客户端。
    • 客户端在后续请求中携带 Token,服务器验证后允许访问。
  2. 简单 token 的组成:uid(用户唯一的身份标识)、time(当前时间的时间戳)、sign(签名,使用某种哈希算法对 uid 和 time 等信息进行处理,生成固定长度的字符串。这个签名可以防止 token 被篡改,保证其安全性)
  3. 特点:
    • 通常是字符串,包含用户信息和签名。
    • 无状态:服务器不需要存储 Token。
  4. 常见用途:
    • API 认证。
    • 分布式系统的鉴权。

身份验证流程:

  1. 客户端使用用户名跟密码请求登录
  2. 服务端收到请求,去验证用户名与密码
  3. 验证成功后,服务端会签发一个 token 并把这个 token 发送给客户端
  4. 客户端收到 token 以后,会把它存储起来,比如放在 cookie 里或者 localStorage 里
  5. 客户端每一次向服务端请求资源的时候都需要带着服务端签发的 token,把 token 放到 HTTP 的 Header 里
  6. 服务端收到请求,然后去验证客户端请求里面带着的 token ,如果验证成功,就向客户端返回请求的数据
  7. 基于 token 的用户认证是一种服务端无状态的认证方式
    • 服务端不用存放 token 数据。
    • 用解析 token 的计算时间换取 session 的存储空间,从而减轻服务器的压力,减少频繁的查询数据库。
  8. token 完全由应用管理,所以它可以避开同源策略

image

# Refresh Token

  1. 另外一种 token —— refresh token
  2. refresh token 是专用于刷新 access token 的 token
    • 如果没有 refresh token,也可以刷新 access token,但每次刷新都要用户输入登录用户名与密码,会很麻烦。
    • 有了 refresh token,可以减少这个麻烦,客户端直接用 refresh token 去更新 access token,无需用户进行额外的操作。
  3. Access Token 的有效期比较短,当 Acesss Token 由于过期而失效时,使用 Refresh Token 就可以获取到新的 Token,如果 Refresh Token 也失效了,用户就只能重新登录了。
  4. Refresh Token 及过期时间是存储在服务器的数据库中,只有在申请新的 Acesss Token 时才会验证,不会对业务接口响应时间造成影响,也不需要向 Session 一样一直保持在内存中以应对大量的请求。

验证流程:

image

# Token 和 Session 的区别

  1. 状态性不同
    • Session 是一种记录服务器和客户端会话状态的机制,使服务端有状态化,可以记录会话信息。
    • 而 Token 是令牌,访问资源接口(API)时所需要的资源凭证。Token 使服务端无状态化,不会存储会话信息。
  2. Session 和 Token 并不矛盾
    • token,每一个请求都有签名还能防止监听以及重放攻击,
    • 而 Session 就必须依赖链路层来保障通讯安全了。
    • 如果你需要实现有状态的会话,仍然可以增加 Session 来在服务器端保存一些状态。
  3. 简单来说:
    • 如果你的用户数据可能需要和第三方共享,或者允许第三方调用 API 接口,用 Token。
    • 如果永远只是自己的网站,自己的 App,用什么就无所谓了。
属性 Token Session
存储位置 客户端(通常在 LocalStorage 或 Cookie 中) 服务器端
状态性 无状态 有状态
扩展性 适合分布式系统 适合单服务器系统
安全性 存储在客户端,需防止泄露 存储在服务器,更安全

# 四、什么是 JWT

  1. JWT(JSON Web Token)是为了在网络应用环境间传递声明而执行的一种基于 JSON 的开放标准,用于在客户端与服务器之间安全地传递信息。
    • 信息以 JSON 格式存储,结构分为三部分:Header、Payload、Signature。
    • 流行的跨域认证解决方案。
    • 是一种认证授权机制。
  2. 结构:
    • Header:元信息(类型和签名算法)。
    • Payload:数据负载(用户信息、权限等)。
    • Signature:签名,用于验证数据完整性。
  3. 特点:
    • 自包含:JWT 包含了身份信息,无需额外查询数据库。
    • 无状态:服务器不存储 JWT。
    • 易于扩展,适合微服务架构。
  4. 使用场景:
    • 用户认证。
    • 单点登录(SSO)。

更多细节:JWT 基础小结 | 沉梦听雨的编程指南 (opens new window)

# Token 和 JWT 的区别

相同:

  • 都是访问资源的令牌
  • 都可以记录用户的信息
  • 都是使服务端无状态化
  • 都是只有验证成功后,客户端才能访问服务端上受保护的资源

区别:

  • Token:服务端验证客户端发送过来的 Token 时,还需要查询数据库获取用户信息,然后验证 Token 是否有效。
  • JWT: 将 Token 和 Payload 加密后存储于客户端,服务端只需要使用密钥解密进行校验(校验也是 JWT 自己实现的)即可,不需要查询或者减少查询数据库,因为 JWT 自包含了用户信息和加密的数据。
属性 Token JWT
格式 自定义 标准格式(Header.Payload.Signature)
状态性 无状态 无状态
信息存储 通常不包含用户信息 自包含用户信息
验证方式 自定义 基于签名验证

# 常见的前后端鉴权方式

  1. Cookie + Session
    • 客户端使用 Cookie 存储 Session ID。
    • 服务器通过 Session ID 识别用户身份。
  2. Token-based Authentication
    • 客户端使用 Token 请求受保护资源。
    • 服务器验证 Token 有效性。
  3. JWT Authentication
    • 客户端携带 JWT,服务器通过签名验证。
  4. OAuth 2.0(开放授权)
    • 第三方授权协议,适用于开放平台。

# 常见的加密算法

  1. 哈希算法
    • MD5、SHA-1、SHA-256。
    • 不可逆,加密后无法还原。
  2. 对称加密
    • AES、DES。
    • 加密和解密使用同一密钥。
  3. 非对称加密
    • RSA、ECC。
    • 使用公钥加密,私钥解密。
  4. 签名算法
    • HMAC(基于哈希的消息认证码)。
    • 用于验证消息完整性和身份。

哈希算法:

  • 将数据重新打乱混合,重新创建一个哈希值
  • 正像快速:原始数据可以快速计算出哈希值
  • 逆向困难:通过哈希值基本不可能推导出原始数据
  • 输入敏感:原始数据只要有一点变动,得到的哈希值差别很大
  • 冲突避免:很难找到不同的原始数据得到相同的哈希值

# 常见问题

# 使用 Cookie 时需要考虑的问题

  1. 安全性:
    • 设置 Secure 属性:如果为 true,则只有在 HTTPS 连接时,cookie 才能被发送。
    • 设置 HttpOnly 属性:防止 JavaScript 访问 cookie,增加抵御 XSS 攻击的能力。
    • 设置 SameSite 属性:防止 CSRF 攻击。可以设置为 Strict、Lax 或 None,确保 cookie 仅在同一站点请求时发送。
  2. 存储大小限制:
    • Cookie 的大小通常受限于 4KB,因此不适合存储大量数据。
  3. 跨域问题:
    • 不同域之间的 cookie 默认无法共享。需要在服务器端进行跨域配置,或者使用 Access-Control-Allow-Credentials 和 Access-Control-Allow-Origin 配置。
  4. 性能影响:
    • 每次请求都会带上 cookie,可能会影响性能,特别是在数据量较大时。

# 使用 Session 时需要考虑的问题

  1. 存储位置:
    • Session 数据通常存储在服务器端,但可以选择存储在内存、数据库或分布式缓存中。需要根据应用场景和访问量选择合适的存储方式。
  2. Session ID 管理:
    • Session ID 通常存储在 cookie 中,需要确保 ID 的安全性。使用 HttpOnly 和 Secure 来提高安全性。
    • 避免暴露 Session ID,防止会话劫持。
  3. 会话过期与清除:
    • 设置合适的会话超时和过期时间,避免泄露敏感信息。需要有机制定期清除过期的 Session 数据。
  4. 分布式系统:
    • 在分布式系统中,Session 的共享和同步变得更加复杂。常用的解决方案包括使用 Redis 等分布式缓存来存储 Session 数据。

# 使用 Token 时需要考虑的问题

  1. 存储方式:
    • Token 通常存储在客户端,常见存储方式包括 LocalStorage 和 SessionStorage。如果使用 cookie,需要确保设置适当的属性(如 HttpOnly、Secure)。
  2. 过期机制:
    • Token 一般有有效期,过期后需要重新获取。可以通过在 Token 中存储过期时间来管理。
  3. 刷新机制:
    • 如果 Token 过期后,通常需要一个刷新 Token(Refresh Token)来重新获取新的访问 Token。
  4. Token 安全性:
    • 确保 Token 不容易被窃取,尤其是在客户端存储时。如果使用 JWT,密钥管理非常重要。
  5. 跨域支持:
    • Token 通常用于跨域认证,确保服务器的 CORS 配置支持跨域请求。

# 使用 JWT 时需要考虑的问题

  1. 签名和密钥管理:
    • JWT 是通过签名进行验证的,确保签名算法(如 HMAC、RSA、ECDSA)和密钥的安全性。如果密钥泄露,攻击者可以伪造有效的 JWT。
  2. 过期时间设置:
    • 在 JWT 中设置过期时间(exp),确保过期后不能再使用。合理的过期时间有助于减少 Token 被滥用的风险。
  3. 防止重放攻击:
    • 可以使用 jti(JWT ID)字段来唯一标识每个 JWT,防止同一个 JWT 被多次使用。
  4. Token 大小:
    • JWT 中包含了用户信息和其他数据,可能导致 Token 比较大。在某些高频请求中,较大的 Token 会影响性能。
  5. 刷新机制:
    • 使用 Refresh Token 机制,确保长时间会话保持有效,同时限制主 Token 的使用时长。

# 使用加密算法时需要考虑的问题

  1. 算法选择:
    • 根据不同的应用需求选择适当的加密算法。常见的有对称加密(如 AES)和非对称加密(如 RSA)。对称加密速度较快,非对称加密更适合用于密钥交换和数字签名。
  2. 密钥管理:
    • 密钥的管理非常关键。密钥应当存储在安全的地方(例如使用硬件安全模块 HSM 或密钥管理服务 KMS)。密钥泄露会使得加密数据完全暴露。
  3. 加密强度:
    • 确保使用合适长度的密钥和强加密算法,避免使用已被破解或不再安全的算法(如 MD5、SHA1)。
  4. 性能问题:
    • 加密和解密操作可能会增加性能负担,特别是在高并发环境下。因此,在设计时要权衡加密强度与性能需求。
  5. 避免重放攻击:
    • 在使用加密进行认证时,增加时间戳、唯一标识符等机制,防止重放攻击。
  6. 加密模式:
    • 在使用对称加密时,选择合适的加密模式(如 CBC、GCM)。不同模式有不同的安全性和性能特性,选择时要根据实际需求评估。

# 只要关闭浏览器 ,session 真的就消失了?

不一定。Session 的生命周期取决于它的存储方式和服务器的配置。通常有以下几种情况:

  1. 浏览器关闭后 Session 失效:
    • 默认情况下,当 Session 存储在浏览器的内存中(如使用 Cookie 存储 Session ID),并且没有设置 Expires 或 Max-Age 属性时,浏览器关闭后,存储的 Session 信息会被清除,这意味着 Session 会失效。
    • 如果 Session 是存储在浏览器的 sessionStorage 中,那么一旦浏览器关闭,sessionStorage 中的数据也会被清除。
  2. Session 不会因为浏览器关闭而消失:
    • 如果 Session 存储在 服务器端(大多数情况下是这样),那么即使用户关闭浏览器,Session 数据依然存在于服务器的存储(如内存、数据库、Redis 等)。这时,Session 依然有效,直到过期时间到达,或者显式地从服务器端销毁。
    • 如果使用 持久化 Cookie(通过设置 Expires 或 Max-Age),则即使浏览器关闭,只要 Cookie 没过期,Session ID 依然会被保留,浏览器重新打开时,Session 可以继续有效。
  3. Session 超时:
    • 即使 Session 没有在浏览器关闭时消失,也会受到会话超时(session timeout)的影响。服务器一般会设置一个会话超时时间(比如 30 分钟),当用户的 Session 在设定时间内没有任何请求,Session 会被自动销毁。

总结

  1. 如果 Session ID 存储在浏览器 Cookie 中,且没有设置持久化 Cookie,浏览器关闭后 Session 通常会丢失。
    • 关闭浏览器后这个 session id 就消失了,由于客户端无法找到 Session ID,因此它无法再与服务器端的 Session 关联,从而 客户端认为 Session 丢失。
    • 不是 Session 立即消失,直到 Session 过期或被清除(会话超时自动销毁),服务器端的 Session 数据才会消失。
    • 如果服务器设置的 cookie 被保存在硬盘上,或者使用某种手段改写浏览器发出的 HTTP 请求头,把原来的 session id 发送给服务器,则再次打开浏览器仍然能够打开原来的 session。
  2. 如果 Session 存储在服务器端,浏览器关闭不会影响服务器上的 Session 存储。
  3. 如果设置了 Session 的过期时间,无论浏览器是否关闭,超时后 Session 会被销毁。

因此,是否消失取决于 Session 的存储位置和设置。

# 学习参考

  • https://www.iocoder.cn/Fight/Confused-about-cookies-sessions,-Tokens-JWT/?yudao (opens new window)
上次更新: 2025/1/3 18:05:41
什么是RBAC权限模型?
深入了解 Bearer 模式

← 什么是RBAC权限模型? 深入了解 Bearer 模式→

Theme by Vdoing | Copyright © 2023-2025 沉梦听雨 | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式