FastAPI从入门到实战(8)——一文弄懂Cookie、Session、Token与JWT

2023-11-18

看到标题应该也能看出来本文讲的就是前端鉴权相关的内容了,鉴权也就是身份认证,指验证用户是否有系统的访问权限,只要是web开发,这部分内容就是不可能不学的,很多面试也必问,所以本文就针对此主题详细记录一下其常见的几种方式。

HTTP状态

HTTP 是无状态的。也就是说,HTTP 请求方和响应方间无法维护状态,都是一次性的,它不知道前后的请求都发生了什么。但有的场景下,我们需要维护状态。最典型的,一个用户登陆微博,发布、关注、评论,都应是在登录后的用户状态下的。这种情况下,各种鉴权就应运而生了。

在此之前还了解一点基本的概念:

  • 认证

认证就是验证当前用户的身份,比如用户名密码登录认证、邮箱发送登录链接、手机号验证码认证。认证当前用户就是本人,不是机器。

  • 授权

用户授予第三方应用访问用户某些资源的权限,客户端授予服务器端应用的一些权限,最常见的就是安装手机应用时,APP询问用户是否授予媒体访问权限。

  • 凭证

实现认证和授权就需要有东西来标识访问者的身份,这个标识就是凭证,如银行,去大厅逛逛,不需要办业务就不需要认证,也就不需要凭证,逛逛就走了;但是要办业务的话就需要提供身份证明和银行卡信息,身份证和银行卡就对应到了凭证,拿着凭证就可以在银行进行认证办业务了。

Cookie

参考链接:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Cookies

Cookie是服务器发送到用户浏览器并保存在本地的一些数据,浏览器会将cookie进行存储,在下次向浏览器发送请求的时候,会一并将cookie也发送到服务器上,这样服务器就能知道这两个请求是不是来自同一浏览器了。

cookie222

Cookie主要在以下三个方面发挥的很淋漓尽致:

  • 会话状态管理

​ 比如最最常见的用户登录状态,客户端登录的时候发送一个请求,服务器接收到请求后进行验证,验证成功发送一个请求成功和setcookie的响应,客户端收到响应后完成登录的同时进行cookie的存储,下一次进行页面刷新、跳转等操作的时候,会将cookie一并发送给服务器。服务器接收cookie并进行验证,验证成功便直接发出响应,验证失败跳转到登录页面重新登录。

  • 个性化设置

​ 比如用户自定义设置、主题设置,与上面同样的道理,进行设置和验证即可保证有效期内的用户自定义设置。

  • 浏览器行为跟踪

​ 由于http都是无状态的,所以服务器无法判断当前请求的发送者是不是同一个人,服务器与浏览器进行会话,服务器就能知道浏览器的行为情况,进一步便能进行追踪。

Cookie应用

这一部分的内容参见下一节,直接通过代码的形式进行展示与讲解。

Session

客户端发送请求,服务器会为了这个请求创建一个内存空间,这个对象就是session对象,在创建session的同时,会生成一个sessionid,并通过Set-Cookie:JSESSIONID=XXXXXXX的命令发送一个cookie的设置,客户端收到响应便在浏览器设置了一个cookie信息,cookie结束的时候,这一次会话也就结束了。

接下来客户端的所有请求,请求头都会带上携带有sessionid的cookie信息,然后服务器通过读取请求头中的cookie信息回去sessionid,进一步进行session的验证,进行会话的继续。

  • session的缺点

​ session是存储在服务器上的,如果是分布式的架构,那么很可能会面临失效的问题。

Session应用

后面实战项目中应该会涉及,这里不进行试验了。

Cookie和Session的区别

  • 安全性

​ Session 比 Cookie 安全,Session 是存储在服务器端的,Cookie 是存储在客户端的。

  • 存取值的类型不同

​ Cookie 只支持存字符串数据,想要设置其他类型的数据,需要将其转换成字符串,Session 可以存任意数据类型。

  • 有效期不同

​ Cookie 可设置为长时间保持,比如我们经常使用的默认登录功能,Session 一般失效时间较短,客户端关闭(默认情况下)或者 Session 超时都会失效。

  • 存储大小不同

​ 单个 Cookie 保存的数据不能超过 4K,Session 可存储数据远高于 Cookie,但是当访问量过多,会占用过多的服务器资源。

Token

Token 的中文意思是"令牌"。主要用来身份验证。比传统的身份验证方法,Token 有扩展性强,安全性高的特点,非常适合用在 Web 应用或者移动应用上。它是服务器生成的字符串,可以作为客户端的一个凭证。

session的设置对于中小型的项目来讲,是比较合适的,但是一旦流量大起来,服务器要保存的数据就太多了,对服务器的消耗是巨大的。

针对这个问题,就想能不能不在服务器中进行保存了,去客户端保存,比如用户登录了系统,服务器就给客户端发送一个token,里面包含了用户的id,下一次请求的时候,把这个token又带回来,但是这样还是有问题,这个是容易伪造的,所以就需要做一个加密,别人就无法伪造了。

这个token服务器不保存,当用户把这个token 给我发过来的时候,我再用同样的算法和密钥,对数据计算一次签名, 和token 中的签名做个比较, 如果相同, 我服务器就知道用户已经登录过了,并且可以直接取到用户的id , 如果不相同, 数据部分肯定被人篡改过,服务器就返回验证失败的错误。

  • 和cookie的不同

最开始我看到这里的时候,就已经迷糊了,生成数据发送到客户端,客户端每次请求都会发送给服务器,这和cookie有什么区别呢?

但是细想一下就知道很不一样了,cookie是一个数据块,可以保存很多键值对数据,token是一个令牌,这个令牌只保存验证需要用的数据。token可以放在url中、header中、请求体中,也可以放在cookie中,本质上就是一条数据。

  • 总结一下验证的流程
  1. 客户端使用用户名和密码请求登录
  2. 服务端收到请求,验证用户名和密码
  3. 验证成功后,服务端会签发一个token,再把这个token返回给客户端
  4. 客户端收到token后可以把它存储起来,比如放到cookie中
  5. 客户端每次向服务端请求资源时需要携带服务端签发的token,可以在cookie或者header中携带
  6. 服务端收到请求,然后去验证客户端请求里面带着的token,如果验证成功,就向客户端返回请求数据

Token对比Session

session和token并不矛盾,session是一种存储机制,目的是存储登录信息;token是为了提供认证和授权,加密的数据是用户信息,服务器拿到需要和数据库对比,进行用户认证。

  • 支持跨域访问

​ cookie是无法跨域的,而token由于没有用到cookie(前提是将token放到请求头中),所以跨域后不会存在信息丢失问题

  • 无状态

​ token机制在服务端不需要存储session信息,因为token自身包含了所有登录用户的信息,所以可以减轻服务端压力

  • 更适用CDN

​ 可以通过内容分发网络请求服务端的所有资料

  • 更适用于移动端

​ 当客户端是非浏览器平台时,cookie是不支持的,采用token认证方式会简单很多

  • 无需考虑CSRF

​ 由于不再依赖cookie,所以采用token认证方式不会发生CSRF,所以也就无需考虑CSRF的防御

JWT

JWT是token的一种实现方式,其全称是JSON Web Token。官网:https://jwt.io/

JWT将用户信息保存在一个Json字符串中,然后进行编码就得到了一个JWT token,而且JWT带有签名信息,接收后可以进行校验,所以可以用于在各方之间安全地将信息作为Json对象传输。

  • JWT的认证流程:
  1. 前端将用户信息通过表单发送到后端
  2. 后端拿到信息和数据库进行比对,核验成功后,将包含用户信息的数据作为JWT的主要载荷,然后结合JWT Header进行编码后进行签名,就得到了一个JWT Token
  3. 后端将JWT Token字符串作为登录成功的结果返回给前端。前端可以将返回的结果进行存储,退出浏览器的时候删除即可
  4. 前端发送请求的时候把JWT Token放置到HTTP请求头中的Authorization属性中(解决XSS和XSRF的问题)
  5. 后端检查前端传过来的JWT Token后进行验证
  6. 验证通过后,后端解析JWT Token中包含的信息,进行进一步的处理

JWT结构

JWT由3部分组成:标头(Header)、有效载荷(Payload)和签名(Signature)。在传输的时候,会将JWT的3部分分别进行Base64编码后用.进行连接形成最终传输的字符串:

Base64(Header).Base64(Payload).HMACSHA256(base64UrlEncode(header)+"."+base64UrlEncode(payload),secret)

Header

JWT头是一个描述JWT元数据的JSON对象,alg属性表示签名使用的算法,默认为HMAC SHA256(写为HS256);typ属性表示令牌的类型,JWT令牌统一写为JWT。最后,使用Base64 URL算法将上述JSON对象转换为字符串保存:

{
  "alg": "HS256",
  "typ": "JWT"
}

Payload

有效载荷部分,是JWT的主体内容部分,也是一个JSON对象,包含需要传递的数据。 JWT指定七个默认字段供选择:

iss:发行人
exp:到期时间
sub:主题
aud:用户
nbf:在此之前不可用
iat:发布时间
jti:JWT ID用于标识该JWT

除以上默认字段外,我们还可以自定义私有字段,一般会把包含用户信息的数据放到payload中:

{
  "sub": "1234567890",
  "name": "MinChess",
  "admin": true
}

Signature

签名哈希部分是对上面两部分数据签名,需要使用base64编码后的header和payload数据,通过指定的算法生成哈希,以确保数据不会被篡改。首先,需要指定一个密钥(secret)。该密码仅仅为保存在服务器中,并且不能向用户公开。然后,使用header中指定的签名算法(默认情况下为HMAC SHA256)根据以下公式生成签名

HMACSHA256(base64UrlEncode(header)+"."+base64UrlEncode(payload),secret)

在计算出签名哈希后,JWT头,有效载荷和签名哈希的三个部分组合成一个字符串,每个部分用.分隔,就构成整个JWT对象

JWT的种类

JWT(JSON Web Token)指的是一种规范,这种规范允许使用JWT在两个组织之间传递安全可靠的信息,JWT的具体实现可以分为以下几种:

  • nonsecure JWT:未经过签名,不安全的JWT

    header中没有指定签名算法,只有algtyp,就更没有签名了。

  • JWS:经过签名的JWT

    JWS就是在header中指定了算法,最后也有对应签名的token。

  • JWE:payload部分经过加密的JWT

    JWE就是载荷数据加密过的JWT,这样不能直接解析出载荷的明文数据

JWT总结

JWT就是Token的一种规范,三个部分,头+载荷+签名,头中声明类型、加密算法等,载荷装载主要数据,签名由算法+头+载荷+密钥组成,token也是三个部分,前面两个部分是明文的,前端可以直接进行解析获取到有效数据,所以不能放敏感数据;

最开始没弄懂的时候,到这里还不知道为什么要加密,加密了也是明文,加密有什么意义,后来弄明白了才后知后觉,加密只是保证前面两部分的数据不会被修改,修改了就返回错误。

验证的过程是,服务器拿到数据,对header和payload进行解码进一步对解码的结果结合密钥进行一次签名,然后将结果和客户端返回回来的签名对比,对比不同即返回错误。

个人感觉记录的还是相对清晰的,具体的实战都在后面进一步进行操作。

最开始没弄懂的时候,到这里还不知道为什么要加密,加密了也是明文,加密有什么意义,后来弄明白了才后知后觉,加密只是保证前面两部分的数据不会被修改,修改了就返回错误。

验证的过程是,服务器拿到数据,对header和payload进行解码进一步对解码的结果结合密钥进行一次签名,然后将结果和客户端返回回来的签名对比,对比不同即返回错误。

个人感觉记录的还是相对清晰的,具体的实战都在后面进一步进行操作。


感谢阅读!
博客地址:FastAPI从入门到实战(8)——一文弄懂Cookie、Session、Token与JWT

欢 迎 关 注 博 主 个 人 小 程 序!
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

FastAPI从入门到实战(8)——一文弄懂Cookie、Session、Token与JWT 的相关文章

随机推荐

  • 服务器磁盘性能多少分正常,服务器内存使用率多少为正常

    服务器内存使用率多少为正常 内容精选 换一换 当您发现云服务器的运行速度变慢或云服务器突然出现网络断开现象 则可能是云服务器的带宽和CPU使用率过高导致 如果您已经通过云监控服务创建过告警任务 当CPU或带宽利用率高时 系统会自动发送告警给
  • 微弱直流电压/电流信号的采样电路 --滤波跟随放大

    要求将待测的电压 1mV 1000mV 电流 1mA 100mA 采样出来传给单片机 我的思路是 电压采样先用放大电路放大 再进行滤波 把50Hz的交流电干扰滤除 然后再进行模数转换传给单片机 电流的话用一个采样电阻 然后对其电压采样后推算
  • 信息学奥赛一本通【1034:计算三角形面积】

    题目描述 平面上有一个三角形 它的三个顶点坐标分别为 x1 y1 x2 y2 x3 y3 x1 y1 x2 y2 x3 y3 那么请问这个三角形的面积是多少 精确到小数点后两位 输入 输入仅一行 包括66个单精度浮点数 分别对应x1 y1
  • 关于git的一些命令,实验记录

    1 下载moduleA项目代码 命令 git clone https github com wangyanan52121 moduleA git 因网络问题 可能会下载失败 多试几次 2 查看当前项目 查看tag命令 字符串排序 git C
  • 语言深入理解指针(非常详细)(三)

    目录 数组名的理解 使用指针访问数组 一维数组传参的本质 二级指针 指针数组 指针数组模拟二维数组 数组名的理解 在上 个章节我们在使用指针访问数组的内容时 有这样的代码 int arr 10 1 2 3 4 5 6 7 8 9 10 in
  • mysql如何一秒插入10万条数据

    当我们需要批量插入或者更新记录时 可以采用Java的批量更新机制 该机制允许多条语句甚至一次性提交给数据库处理 通常情况下比一句一提交处理更有效率 jdbc处理批量提交有三个方法 需要注意的是 这三种方法都要和PreparedStateme
  • Rx与Async Task的简单对比

    有关Reactive Extensions的介绍可见https rx codeplex com 总的来说 你可以当它是又一个异步编程的框架 它以观察者模式实现了对数据流的的 订阅 一个列表 一个事件 一个耗时操作的方法 等等 都可以Obse
  • C++ 多线程std::async

    std async 对于线程的创建 我们可以直接用thread 但是这会有很多的不便 比如获取子进程的返回值 解决方案是定义一个变量 然后将变量的指针传入到子进程中 然后对其进行赋值 但终归是不便 除此之外我们可以用std async函数来
  • 如何正确理解开漏输出和推挽输出

    作者 知乎用户 链接 https www zhihu com question 28512432 answer 41217074 来源 知乎 著作权归作者所有 商业转载请联系作者获得授权 非商业转载请注明出处 我觉得下面这个 网上资料 还是
  • java项目如何实现数据恢复_Java web 项目中对数据库备份和恢复

    说白了 还是去调用cmd实现数据库的备份和还原功能 备份 mysqldump hserverUrl uusername ppassword dbname gt savePath 还原 mysql hserverUrl uusername p
  • 一文读懂SpringCloud全家桶

    一 云原生应用 SpringCloud是对Springboot使用的分布式解决方案 适合分布式 中大型的项目架构开发 现在也逐渐成为Java服务端的主流框架 使用Spring Cloud开发的应用程序非常适合在Docker和PaaS 比如P
  • C# 提交报错:Validation of viewstate MAC failed 解决办法

    出现以下报错 验证视图状态 MAC 失败 如果此应用程序由网络场或群集承载 请确保
  • 【STM32】SPI初步使用 读写FLASH W25Q64

    硬件连接 1 SS Slave Select 从设备选择信号线 常称为片选信号线 每个从设备都有独立的这一条 NSS 信号线 当主机要选择从设备时 把该从设备的 NSS 信号线设置为低电平 该从设备即被选中 即片选有效 接着主机开始与被选中
  • MySQL 8.0 多实例的配置应用

    文章目录 同版本多实例 配置 部署 启动 连接 不同版本多实例 配置 初始化 initialize insecure 含义 启动 同版本多实例 配置 mkdir p data 330 7 9 data chown R mysql mysql
  • 同城双活与异地多活架构分析

    本文首发于 vivo互联网技术 微信公众号 链接 https mp weixin qq com s OjfFcjnGWV5kutxXndtpMg 作者 vivo官网商城开发团队 采用高可用系统架构支持重要系统 为关键业务提供7x24的不间断
  • Win32 UDP Socket通信学习

    学习内容 参见 Windows网络编程 第7章 Winsock基础 与TCP流式协议不同 UDP为数据报协议 服务端接受数据 客户端发送数据 UDP服务端流程 Socket或WSASocket建立套接字 用SOCK DGRAM标志 bind
  • bootstrap--栅格系统详解(源码分析)

    目录 1 bootstrap是什么 2 栅格模型设计的精妙之处 3 预备知识 4 栅格系统的框架 4 1bootstrap容器 4 1 1固定容器与流体容器公共样式 4 1 2固定容器样式 4 2 bootstrap行与列 4 2 1行 4
  • js中的navigator对象 用js判断浏览器类型

    navigator对象 window navigator返回一个navigator对象的引用 可以用它来查询一些关于运行当前脚本的应用程序的相关信息 在浏览器打印一下navigator对象 console log navigator MDN
  • 基于Nonconvex规划的配电网重构研究(Matlab代码实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 3 参考文献 4 Matlab代码实现 1 概述 本文基于Nonconvex规划的配电网重构
  • FastAPI从入门到实战(8)——一文弄懂Cookie、Session、Token与JWT

    看到标题应该也能看出来本文讲的就是前端鉴权相关的内容了 鉴权也就是身份认证 指验证用户是否有系统的访问权限 只要是web开发 这部分内容就是不可能不学的 很多面试也必问 所以本文就针对此主题详细记录一下其常见的几种方式 HTTP状态 HTT