Cookie、Session、JWT 那些事

news/2024/4/25 7:16:27/文章来源:https://blog.csdn.net/ldw201510803006/article/details/129191688

文章目录

  • 前言
  • 一、概念
    • 1、Cookie:
    • 2、Session:
    • 3、JWT
  • 二、应用
    • 1. 基本使用
    • 2. 实现 “退出” 功能
  • 总结


前言

目前 C/S 模式盛行,HTTP 是其中最常见的通信协议,我们知道 HTTP 协议是无状态的,但是这场景完全不够用。

比如,我们微信扫描登录一个网站后,肯定不希望频繁登录嘛,那我们的诉求就是希望在一段时间内,网站能够 “记忆” 我们的登录状态,而这个 “记忆” 的能力 HTTP 是没法完成的,所以需要我们额外做点什么 …

你想想,两端通信过程,状态信息要么存在客户端、要么存在服务端,简言之,现在的问题是,要如何存、存哪里的问题。

当然,这块技术已经很成熟了,我们只需要学会怎么去用就 OK 了。

而本文的主角:Cookie、Session、JWT 这些技术就是专门来解决这类问题的。


一、概念

1、Cookie:

前面我们提到,通信状态可以保存在客户端,这里的客户端一般指我们的浏览器,而浏览器就提供了 Cookie 这么一门技术,简单理解就是以 Key / Value 形式存储数据。

当我们向服务器发起请求的时候,就会在 HTTP 请求头上携带上 Cookie 信息,传递到服务端,由服务端进行处理。

什么是 Cookie?

Cookie 是一段不超过 4KB 的小型文本数据,由一个名称(Name)、一个值(Value)和其它几个用于控制 Cookie 有效期、安全性、使用范围的可选属性组成。

安全性?

Cookie 有自身的一些限制,同时也存在一些安全性的问题,比如 不支持跨域、Cookie 容易被窃取 等,所以,你在使用的时候你需要注意!

2、Session:

会话。字如其名,好比你通过微信和朋友聊天,是不是要先进入对话窗口?这个对话窗口,就可以理解成一个简单的会话。

我俩聊天,前前后后说的这些话,一时半会都刻在双方脑子里,不是那种说完就忘了的,会话也是这个理,它有上下文、也是有记忆的、只不过这个记忆就需要客户端或者服务端来 “记” 下来。

既然是对话,肯定涉及两方,因此客户端、服务端一个都不能缺,是吧?

我们再看,通常我们的服务端是中心化的,可以承接千千万万的客户端连接,我们要如何管理这千千万万的连接呢?

在服务端来中心化的管理这些连接,我们也习惯称 会话管理,本质就是管理这些对话状态嘛。

具体怎么用呢?

用户 A 进行了登陆,服务端记录登录状态,并创建一次会话,服务端这边保存了用户的会话数据(用户id、姓名 …),并给这次会话分配全局唯一ID,也称为会话ID(sessionId)。

有效期内,在服务端我们可以通过这个 sessionId 直接定位到其对应的会话状态。

当然,还没完,客户端想要和服务端通信,手里总的拿点凭证吧?于是我们就把这个 sessionId 返回给客户端,客户端怎么存呢?

Cookie,你看,这就串联起来了!

用户登录后,服务端返回 sessionId,然后客户端将 sessionId 存到 Cookie 中,每次请求服务端时,从 Cookie 中取出 sessionId,并放置到请求头中,然后服务端直接从请求头中取出来用就可以了。

3、JWT

所有信息都放在服务端来存储,服务端的压力是不是有点大?能不能将这些压力分担到千千万万的客户端?

答案是可以的,这就是我们目前常用的 JWT 技术。

全称:JSON Web Token,是一个开放标准(RFC 7519),它定义了一种紧凑的、自包含的方式,用于作为 JSON 对象在各方之间安全地传输信息。该信息可以被验证和信任,因为它是数字签名的。

简单说,我们的信息通过特殊方式处理后,就能得到一串相对精简的字符串,也常叫 token,而我们也可以通过这个 token 反解析出具体的信息,这就是 JWT 的处理思路。

有了这种技术之后,在某些场景之下,我们就不需要在服务端中心化的存储这些 会话 状态了,因为这些会话数据都交给了客户端自己保管,每次请求时都会带上。

那服务端怎么验证这个会话呢?前面提到,我们可以直接从 token 解析出用户会话数据,一般就包括用户 id,昵称 等,基本上够用了。

诶,听起来很完美?

别急,凡是有利有弊,服务端不再中心化的记录这些会话状态,最大的问题就是没法管理会话。比如,你想要实现 “退出” 功能,就没法做到了,至于怎么做,我们后面分析。

JWT:

JWT 分为三段,包括头部、有效负载和签名,它们使用 Base64 进行编码后得到一串字符串,也称为 token,我们看个例子:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJjdXJyZW50LXVzZXIiOiIwOjI4Ouafj-ayuTEyMyIsIngtb3JpZ2luLXN5c3RlbSI6InBpY2h1IiwiZXhwIjoxNjc3NDM4MDAwfQ.-wtyD7woxpgE9fFXjdcUV_mryuwmXvcFGSZuB4dNdZc
  • 头部:声明了编码对象的类型和密码签名的算法。

  • 有效负载:其中包含与令牌有关声明的详细信息。

  • 签名:防止信息被篡改。签名的格式可以是使用共享密钥的对称算法(HS256)或使用公钥和私钥的不对称算法(RS256)。

对于JWT,最好的选择是非对称选项,因为对于需要认证 JWT 的服务而言,它仅需要密钥的公共部分。

我们在线解密看看:

在这里插入图片描述

由于这里使用 Base64 进行编码,并没有进行不可逆的加密,直接进行解码就能得到明文,所以,要避免存放重要信息,防止泄漏。当然,你也可以将重要的信息加密后存放。

JWT 的优点:

在于支持跨语言,JSON 格式提供了语言无关性;同时,Token 占用字节小,便于传输。

JWT 的缺点:

Token 的注销方式。由于 Token 不存储在服务端,当用户注销时,Token 的有效时间可能还没有到,所以如何在用户注销的同时让 Token 失效是实现上的难点。

二、应用

鉴于目前 JWT 的流行,以及在工作中使用的较多,我们就以 JWT 来看看实战效果。

1. 基本使用

当用户登录时,根据用户信息使用 JWT 生成一个 token,然后返回给前端,前端每次向服务端发起请求的时候都带上 token。

服务端接收到请求后,一般是网关来验证 token 的合法性(一般就是简单的反解析)、并从 token 中获取到用户的信息进行使用。

生成 token:

val token = JWT.create().withExpiresAt(Date(System.currentTimeMillis() + expire)).withClaim(CURRENT_USER, "${user.id}:$name").sign(Algorithm.HMAC256(properties.jwtSecret))

你可以看到,我们这里定义了 token 过期时间、必要的用户信息、以及选择的签名算法。

解析 token:

...try {...final List<String> authorization = request.getHeaders().get("authorization");final DecodedJWT jwt = JWT.require(algorithm).build().verify(authorization.get(0));String user = jwt.getClaim(CURRENT_USER).asString();String userId = user.split(":")[0];} catch (JWTDecodeException | SignatureVerificationException te) {throw new JWTException(401, null, "会话已过期");}  catch (TokenExpiredException e) {// 过期token不做处理,由下游拦截log.warn("[Token Filter] 失效token [{}]", authorization);}...

从请求头里取出存放 token 的 authorization 字段,再使用 JWT 进行反编码即可,当 token 无效或者过期会直接抛出异常,我们用 try … catch … 捕获之后按需处理即可。

其实,就这两个简单的步骤,我们就完成了使用 JWT 实现基本的会话状态保存了能力。

2. 实现 “退出” 功能

前面说过,由于 JWT 是非中心化的管理方式,是没法直接做到这个功能的,不过我们可以找点 “野路子”。

分场景来看:

1)一般的后台系统:

如果选择退出登录时,可以让前端直接清理掉浏览器的缓存,这样再去请求接口时,由于请求头没有携带 token,后端会直接返回重定向到登录页面,然后引导用户登录就行了。

那以前的 token 是不是也可以直接用?

是的,所以后端还是要做好 token 有效期的控制,比如 一天、甚至直接让它凌晨某个时间点统一过期点,第二天在强制进行登录即可。

可以看到,这种场景下,我们直接使用 JWT 就可以完成了。

2)C 端:

对 C 端用户这块一般要求就要高点了,这个时候在服务端中心化的维护会话状态就非常有必要了。

我们可以在服务端生成 token 后,顺便在 redis 记录一下 token 的过期时间,然后每次请求时,验证下过期时间。

这种方式和传统的 session 方式很类似?

每次,处理流程上都差不多,但还是有优点:我们这里只记录了 token 过期时间,并没有记录更多的用户信息,所以,相对来说占用的存储空间更小。

在哪里验证 token 有效期?

还是在网关,这是所有请求的入口,方便全局控制。

Cookie 和 Token 有点像?

本质都是 K/V 存储关键信息,token 需要存到浏览器的 localStorage 中,而 Cookie 由浏览器存储到小文本中。

Cookie 是不允许跨域访问的,token 则不存在这个问题。

总结

直接选择 Cookie + Session 这套方案?

可以的,也是非常盛行、经得起时间考验的方案。

选用 JWT?

当然也没问题,优点更突出,目前主流方案。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_75338.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python|每日一练|算法初阶|字符串|树|深度优先搜索|单选记录:循环随机取数组直到得出指定数字|有效数字|平衡二叉树

1、循环随机取数组直到得出指定数字&#xff1f;&#xff08;算法初阶&#xff09; 贡献者&#xff1a;weixin_30937093 举个例子&#xff1a; 随机数字范围&#xff1a;0~100 每组数字量&#xff1a;6&#xff08;s1,s2,s3,s4,s5,s6&#xff09; 第二轮开始随机数字范围&…

Linux 基础介绍-基础命令

文章目录01 学习目标02 Linux/Unix 操作系统简介2.1 Linux 操作系统的目标2.2 Linux 操作系统的作用2.3 Unix 家族历史2.4 Linux 家族历史2.5 Linux 和Unix 的联系2.6 Linux 内核介绍2.7 Linux 发行版本2.8 Unix/Linux 开发应用领域介绍03 Linux 目录结构3.1 Win 和Linux 文件系…

Mac iTerm2 rz sz

1、安装brew&#xff08;找了很多&#x1f517;&#xff0c;就这个博主的好用&#xff09; Mac如何安装brew&#xff1f;_行走的码农00的博客-CSDN博客_mac brew 2、安装lrzsz brew install lrzsz 检查是否安装成功 brew list 定位lrzsz的安装目录 brew list lrzsz 执…

git学习记录/菜鸟教程(基于Gitcode)

首先说明下为何使用Gitcode而不是hub或lab&#xff1a;只是因为国外的网站访问太慢了&#xff0c;而且还要翻译从初次使用开始说&#xff1a;首先安装Git&#xff0c;一路next就可以&#xff0c;安装好后打开&#xff0c;输入git version如果有显示版本号&#xff0c;说明安装成…

2020蓝桥杯真题跑步锻炼(填空题) C语言/C++

题目描述 本题为填空题&#xff0c;只需要算出结果后&#xff0c;在代码中使用输出语句将所填结果输出即可。 小蓝每天都锻炼身体。 正常情况下&#xff0c;小蓝每天跑 1 千米。如果某天是周一或者月初&#xff08;1 日&#xff09;&#xff0c;为了激励自己&#xff0c;小蓝…

Docker在Windows环境的搭建和使用

文章目录安装WSL安装Docker安装Docker镜像下载Docker镜像启动gpu启动传送文件训练yolov5安装WSL Windows10和11支持Docker的安装&#xff0c;安装需要用到WSL。所以&#xff0c;我们先安装WSL。 参考文章&#xff1a;旧版 WSL 的手动安装步骤 以管理员身份打开powershell, 执行…

软考信息系统监理师备考建议

用好备考方法&#xff0c;两三个月就可以过的。信息系统监理师备考最好以教材和历年真题为主&#xff0c;教学视频模拟题为辅。考试介绍与复习建议&#xff1a;考试设置的科目包括&#xff1a;&#xff08;1&#xff09;信息系统工程监理基础知识&#xff0c;考试时间150分钟&a…

Three.js初试——基础概念

一、Three.js 是什么 先附上文档&#xff1a; 官网&#xff1a;JavaScript 3D Library 中文文档&#xff1a;中文文档 Three.js 是一个让用户通过 javascript 入手进入搭建 WebGL 项目的类库。众所周知学习 WebGL 需要图形学知识&#xff0c;而 webgl 需要通过 js 和 glsl …

第八届蓝桥杯省赛——4承压计算(二维数组,嵌套循环)

题目&#xff1a;X星球的高科技实验室中整齐地堆放着某批珍贵金属原料。每块金属原料的外形、尺寸完全一致&#xff0c;但重量不同。金属材料被严格地堆放成金字塔形。7 5 8 7 8 8 9 2 7 2 8 1 4 9 1 8 1 8 8 4 1 7 9 6 1 4 5 4 5 6 5 5 6 9 5 6 5 5 4 7 9 3 5 5 1 7 5 7 9 7 4…

车辆热管理测试方案

车辆热管理是在能源危机出现、汽车排放法规日益严格以及人们对汽车舒适性要求更高的背景下应运而生的。将各个系统或部件如冷却系统、润滑系统和空调系统等集成一个有效的热管理系统&#xff1b;控制和优化车辆的热量传递过程&#xff0c;保证各关键部件和系统安全高效运行&…

社交媒体营销的5个好处

有些人认为&#xff0c;社交媒体营销不能直接与销售挂钩。这就是为什么在制定营销策略时&#xff0c;社交媒体营销会被部分人忽视的原因。然而&#xff0c;与其他广告渠道不同&#xff0c;社交媒体是双向渠道。忽视社交媒体营销将影响与客户的关系。最重要的是&#xff0c;它将…

回顾1-idea创建Java项目

创建Java项目 创建项目和模块的区别 环境前置 IDEA开发工具JDK及配置环境变量 创建项目/工程 新建项目 选择Java模块 > SDK( 已配置的JDK ) > 下一步 直接下一步 填写项目信息 QQ游戏工程 里的 叫项目 所以 QQgame目录下 可以放 > 斗地主项目 / 美女来找茬等… …

C while 循环for循环

C 循环 只要给定的条件为真&#xff0c;C 语言中的 while 循环语句会重复执行一个目标语句。 语法 C 语言中 while 循环的语法&#xff1a; while(condition) {statement(s); }在这里&#xff0c;statement(s) 可以是一个单独的语句&#xff0c;也可以是几个语句组成的代码块…

深度学习基础实例与总结

一、神经网络 1 深度学习 1 什么是深度学习&#xff1f; 简单来说&#xff0c;深度学习就是一种包括多个隐含层 (越多即为越深)的多层感知机。它通过组合低层特征&#xff0c;形成更为抽象的高层表示&#xff0c;用以描述被识别对象的高级属性类别或特征。 能自生成数据的中…

DNS服务器部署的详细操作(图文版)

DNS服务器的部署 打开虚拟机后查看已经开放的端口&#xff0c;可以看到没有TCP53、UDP53&#xff0c;说明DNS服务端口没有打开 打开我的电脑—双击CD驱动器— 选择安装可选的Windows组件 选择网络服务—域名系统&#xff08;DNS&#xff09;— 点击下一步后会弹出如下弹…

线程安全实例分析

一、变量的线程安全分析 成员变量和静态变量是否线程安全&#xff1f; ● 如果它们没有共享&#xff0c;则线程安全 ● 如果它们被共享了&#xff0c;根据它们的状态是否能够改变&#xff0c;又分两种情况 —— 如果只有读操作&#xff0c;则线程安全 —— 如果有读写操作&am…

实时手势识别(C++与python都可实现)

一、前提配置&#xff1a; Windows&#xff0c;visual studio 2019&#xff0c;opencv&#xff0c;python10&#xff0c;opencv-python&#xff0c;numpy&#xff0c;tensorflow&#xff0c;mediapipe&#xff0c;math 1.安装python环境 这里我个人使用的安装python10&#…

ABB机器人基础编程_常见数据类型及使用方法介绍

ABB机器人基础编程_常见数据类型及使用方法介绍 1. bool-逻辑值 描述:bool型数据可以为TRUE或FALSE 使用方法举例: 2. 字节-整数值 描述:byte用于符合字节范围的整数值0-255,该数据类型连同处理操作并转换特征的指令和函数一同使用。 使用方法举例: 3. dnum-双数值 描…

云原生是什么?核心概念和应用方法解析

什么是云原生&#xff1f; 云原生是一种基于容器、微服务和自动化运维的软件开发和部署方法。它可以使应用程序更加高效、可靠和可扩展&#xff0c;适用于各种不同的云平台。 如果要更直接通俗的来解释下上面的概念。云原生更准确来说就是一种文化&#xff0c;是一种潮流&…

供应链的有效管理,分析指标有哪些

对于企业而言&#xff0c;供应链是一个很复杂的、体系化的生态系统&#xff0c;从原材料、到供应商、到生产、仓库、物流&#xff0c;最后到达经销商或者最终客户那里&#xff0c;这个链条很长。相关的分析指标也有很多&#xff0c;在这些指标里面也有非常多可以扩展、延申的内…