Cookie、Session、Token区分
一开始接触这三个东西,肯定会被绕的不知道都是干什么的。
1、为什么要有它们?
首先,由于HTTP协议是无状态的,所谓的无状态,其实就是 客户端每次想要与服务端通信,都必须重新与服务端连接,这就意味着,请求一次,客户端和服务端就连接一次。并且这些请求之间是没有任何关系的。
那这种情况就会造成一个问题:“我”怎么区分这些请求是不是来自于同一个人?
举个例子就是:一个用户在页面A发起了一个请求获取个人信息,然后呢,在另一个页面同样有一个请求要获取个人信息,这要如何确定这两个请求是不是同一个人发的?
为了解决这种问题,首先要解决的就是,知道发起请求的客户端是谁! 这就引出了 cookie、token、session,他们可以解决客户端标识的问题,顺便还能解决一下权限问题。
2、什么是Cookie?
Cookie,有时候也用复数形式Cookies,类型是小型文本文件。是保存在客户端或者说浏览器中的一小块数据,大小限制大致在4KB左右,在以前经常用来存储各种数据,但随着更多浏览器存储方案的出现,cookie存储数据的方式逐渐被取代,主要原因是:
cookie有存储大小的限制,4KB左右
浏览器每次请求会携带cookie在请求头中
字符编码为Unicode,不支持直接存储中文
数据可以被轻易查看
cookie 主要有以下属性:
属性名称 | 属性含义 |
name | cookie 的名称 |
value | cookie 的值 |
comment | cookie 的描述信息 |
domain | 可以访问该 cookie 的域名 |
expires | cookie 的过期时间,具体某一时间 |
maxAge | cookie 的过期时间,比如多少秒后 cookie 过期。 |
path | cookie 的使用路径 |
secure | cookie 是否使用安全协议传输,比如 SSL 等 |
version | cookie 使用的版本号 |
isHttpOnly | 指定该 Cookie 无法通过 JavaScript 脚本拿到,比如 Document.cookie 属性、XMLHttpRequest 对象和 Request API 都拿不到该属性。这样就防止了该 Cookie 被脚本读到,只有浏览器发出 HTTP 请求时,才会带上该 Cookie |
如何通过cookie来实现用户确定或权限确定呢?
通常的登陆操作及后续操作大致过程如下:
客户端发送请求到服务端(比如登录请求)。
服务端收到请求后生成一个 session 会话。
服务端响应客户端,并在响应头中设置 Set-Cookie。Set-Cookie 里面包含了 sessionId。其中 sessionId 就是用来标识客户端的。
客户端收到该请求后,如果服务器给了 Set-Cookie,那么下次浏览器就会在请求头中自动携带 cookie。
客户端发送其它请求,自动携带了 cookie,cookie 中携带有用户信息等。
服务端接收到请求,检测到客户端发送的cookie与其保存的cookie的值保持一致时,直接信任该连接,不再验证,比如通过 sessionId 来判断是否存在会话,存在则正常响应。
cookie 主要有以下特点:
cookie 存储在客户端
cookie 不可跨域,但是在如果设置了 domain,那么它们是可以在一级域名和二级域名之间共享的
3、什么是Session?
在上面所提到的Cookie实现用户权限确认时,提到了session,其实就是会话的意思,session主要是由服务端创建,主要作用就是保存sessionId。 而用户与服务端之间的权限确认主要就是通过sessionId
session 由服务端创建,当一个请求发送到服务端时,服务器会检索该请求里面有没有包含 sessionId 标识。
如果包含了 sessionId,则代表服务端已经和客户端创建过 session,然后就通过这个 sessionId 去查找真正的 session。
如果没找到,则为客户端创建一个新的 session,并生成一个新的 sessionId 与 session 对应,然后在响应的时候将 sessionId 给客户端,通常是存储在 cookie 中。
如果在请求中找到了真正的 session,验证通过,正常处理该请求。
总之每一个客户端与服务端连接,服务端都会为该客户端创建一个 session,并将 session 的唯一标识 sessionId 通过设置 Set-Cookie 头的方式响应给客户端,客户端将 sessionId 存到 cookie 中。
通常情况下,我们 cookie 和 session 都是结合着来用,当然你也可以单独只使用 cookie 或者单独只使用 session,这里我们就将 cookie 和 session 结合着来用。
所以,整个请求过程图,可以粗略分为这么几个过程:
发送登陆请求
创建一个session,并将session的唯一标识sessionId,设置在Set-Cookie响应头中,响应给客户端
发送其他请求并自动携带Cookie,服务端通过sessionId找到session,没找到则重新创建session
Cookie验证通过,正常响应请求
4、Cookie和Session的区别?
在上文中,介绍到它们两者之间主要是通过 sessionId 关联起来的。
所以可以总结为:sessionId 是 cookie 和 session 之间的桥梁。或者可以换个说法,session 是基于 cookie 实现的,它们两个主要有以下特点:
session 比 cookie 更加安全,因为session是存在服务端的,cookie 是存在客户端的。
cookie 只支持存储字符串数据,session 可以存储任意数据。
cookie 的有效期可以设置较长时间,session 有效期都比较短。
session 存储空间很大,cookie 有限制。
系统想要实现鉴权,可以单独使用 cookie,也可以单独使用 session,但是建议结合两者使用。
5、什么是Token?
既然cookie+session可以实现鉴权认证,那为什么还要有token呢?
主要是因为他们的这种认证方式存在一些缺点:
增加请求体积,浪费性能,因为每次请求都会携带 cookie。
增加服务端资源消耗,因为每个客户端连接进来都需要生成 session,会占用服务端资源的。
容易遭受 CSRF 攻击,即跨站域请求伪造。
为了避免上述缺点,token方式的鉴权诞生
Token 通常叫令牌, 最简单的Token组成 :uid(用户唯一身份标识), time(时间戳), sign(签名),还可以把不变的参数也放进token,避免多次查库。 我们将 token 进行解密就可以拿到诸如 uid 这类的信息,然后通过 uid 来进行接下来的鉴权操作。
token 是如何生成的:
cookie 是服务端设置了 set-cookie 响应头之后,浏览器会自动保存 cookie,然后下一次发送请求的时候会自动把 cookie 携带上。而token 主要是由服务器生成,然后返回给客户端,客户端手动把 token 存下来,比如利用 localstorage 或者直接存到 cookie 当中也行。
Token 的使用流程:
A:当用户首次登录成功(注册也是一种可以适用的场景)之后, 服务器端就会生成一个 token 值,这个值,会在服务器保存token值(保存在数据库中),再将这个token值返回给客户端;
B:客户端拿到 token 值之后,进行本地保存;
C:当客户端再次发送网络请求(一般不是登录请求)的时候,就会将这个 token 值附带到参数中发送给服务器;
D:服务器接收到客户端的请求之后,会取出token值与保存在本地(数据库)中的token值做对比。
Token的身份认证逻辑:
对比一:如果两个 token 值相同, 说明用户登录成功过!当前用户处于登录状态!
对比二:如果没有这个 token 值, 则说明没有登录成功;
对比三:如果 token 值不同: 说明原来的登录信息已经失效,让用户重新登录。
总结
鉴权认证方式 | 特点 | 优点 | 缺点 |
cookie | 1.存储在客户端。2.请求自动携带 cookie。 3.存储大小 4KB。 | 1.兼容性好,因为是比较老的技术。 2.很容易实现,因为 cookie 会自动携带和存储。 | 1.需要单独解决跨域携带问题,比如多台服务器如何共享 cookie。 2.会遭受 CSRF 攻击。 3.存储在客户端,不够安全。 |
session | 1.存储在服务端。2.存储大小无限制。 | 1.查询速度快,因为是个会话,相当于是在内存中操作。 2.结合 cookie 后很容易实现鉴权。 3.安全,因为存储在服务端。 | 1.耗费服务器资源,因为每个客户端都会创建 session。 2.占据存储空间,session 相当于存储了一个完整的用户信息。 |
token | 1.体积很小。 2.自由操作存储在哪里。 | 1.安全,因为 token 一般只有用户 id,就算被截取了也没什么用。 2.无需消耗服务器内存资源,它相当于只存了用户 id,session 相当于存储了用户的所有信息。 3.跨域处理较为方便,比如多台服务器之间可以共用一个 token。 | 1.查询速度慢,因为 token 只存了用户 id,每次需要去查询数据库。 |
相关文章:
Cookie、Session、Token区分
一开始接触这三个东西,肯定会被绕的不知道都是干什么的。1、为什么要有它们?首先,由于HTTP协议是无状态的,所谓的无状态,其实就是 客户端每次想要与服务端通信,都必须重新与服务端连接,这就意味…...
回暖!“数”说城市烟火气背后
“人间烟火气,最抚凡人心”。在全国各地政策支持以及企业的积极生产运营下,经济、社会、生活各领域正加速回暖,“烟火气”在城市中升腾,信心和希望正在每个人心中燃起。 发展新阶段,高效统筹经济发展和公共安全&#…...
JS逆向-百度翻译sign
前言 本文是该专栏的第36篇,后面会持续分享python爬虫干货知识,记得关注。 有粉丝留言,近期需要做个翻译功能,考虑到百度翻译语言语种比较全面,但是它的参数被逆向加密了,对于这种情况需要怎么处理呢?所以本文以它为例。 废话不多说,跟着笔者直接往下看正文详细内容。…...
Fiddler抓包之Fiddler过滤器(Filters)调试
Filters:过滤器,帮助我们过滤请求。 如果需要过滤掉与测试项目无关的抓包请求,更加精准的展现抓到的请求,而不是杂乱的一堆,那功能强大的 Filters 过滤器能帮到你。 2、Filters界面说明 fiddler中的过滤 说明&#…...
【xib文件的加载过程 Objective-C语言】
一、xib文件的加载过程: 1.xib文件,是不是在这里啊: View这个文件夹里, 然后呢,我们加载xib是怎么加载的呢, 是不是在控制器里,通过我们这个类方法,加载xib: TestAppView *appView = [TestAppView appView]; + (instancetype)appView{NSBundle *rootBundle = [N…...
react setState学习记录
react setState学习记录1.总体看来2.setState的执行是异步的3.函数式setState1.总体看来 (1). setState(stateChange, [callback])------对象式的setState 1.stateChange为状态改变对象(该对象可以体现出状态的更改) 2.callback是可选的回调函数, 它在状态更新完毕、界面也更新…...
Docker容器cpu利用率问题
1.top原理 top 是读的/proc/stat文件 比如cat /proc/PID/stat 进程的总Cpu时间processCpuTime utime stime cutime cstime,该值包括其所有线程的cpu时间 某一进程Cpu使用率的计算 计算方法: 1 采样两个足够短的时间间隔的cpu快照与进程快照&…...
FreeRTOS入门(06):任务通知
文章目录目的基础说明使用演示作为二进制信号量作为计数信号量作为事件组作为队列或邮箱相关函数总结目的 任务通知(TaskNotify)是RTOS中相对常用的用于任务间交互的功能,这篇文章将对相关内容做个介绍。 本文代码测试环境见前面的文章&…...
谷歌seo做的外链怎样更快被semrush识别
本文主要分享做谷歌seo外链如何能让semrush工具快速的记录并能查询到。 本文由光算创作,有可能会被剽窃和修改,我们佛系对待这种行为吧。 谷歌seo做的外链怎样更快被semrush识别? 答案是:多使用semrush搜索目标网站可加速爬虫抓…...
Java | IO 模式之 JavaBIO 应用
文章目录IO模型Java BIOJava NIOJava AIO(NIO.2)BIO、NIO、AIO的使用场景BIO1 BIO 基本介绍2 BIO 的工作机制3 BIO 传统通信实现3.1 业务需求3.2 实现思路3.3 代码实现4 BIO 模式下的多发和多收消息4.1 业务需求4.2 实现思路4.3 代码实现5 BIO 模式下接收…...
C语言学习及复习笔记-【18】C内存管理
18 C内存管理 C 语言为内存的分配和管理提供了几个函数。这些函数可以在 <stdlib.h> 头文件中找到。 序号函数和描述1void *calloc(int num, int size); 在内存中动态地分配 num 个长度为 size 的连续空间,并将每一个字节都初始化为 0。所以它的结果是分配了…...
linux--多线程(一)
文章目录Linux线程的概念线程的优点线程的缺点线程异常线程的控制创建线程线程ID以及进程地址空间终止线程线程等待线程分离线程互斥进程线程间的互斥相关概念互斥量mutex有线程安全问题的售票系统查看ticket--部分的汇编代码互斥量的接口互斥量实现原理探究可重入和线程安全常…...
计算机组成原理(2.1)--系统总线
目录 一、总线基本知识 1.总线 2.总线的信息传送 3.分散连接图 4.注 二、总线结构的计算机举例 1.面向 CPU 的双总线结构框图 2.单总线结构框图 3.以存储器为中心的双总线结构框图 三、总线的分类 1.片内总线 2.系统总线 (板级总线或板间总线&#…...
C语言数组【详解】
数组1. 一维数组的创建和初始化1.1 数组的创建1.2 数组的初始化1.3 一维数组的使用1.4 一维数组在内存中的存储2. 二维数组的创建和初始化2.1 二维数组的创建2.2 二维数组的初始化2.3 二维数组的使用2.4 二维数组在内存中的存储3. 数组越界4. 数组作为函数参数4.1 冒泡排序函数…...
并行与体系结构会议
A类会议 USENIX ATC 2022: USENIX Annual Technical Conference(录用率21%) CCF a, CORE a, QUALIS a1 会议截稿日期:2022-01-06 会议通知日期:2022-04-29 会议日期:2022-07-11 会议地点:Carlsbad, Califo…...
【巨人的肩膀】JAVA面试总结(三)
1、💪 目录1、💪1、说说List, Set, Queue, Map 四者的区别1.1、List1.2、Set1.3、Map2、如何选用集合4、线程安全的集合有哪些?线程不安全的呢?3、为什么需要使用集合4、comparable和Comparator的区别5、无序性和不可重复性的含义…...
嵌入式 STM32 SHT31温湿度传感器
目录 简介 1、原理图 2、时序说明 数据传输 起始信号 结束信号 3、SHT31读写数据 SHT31指令集 读数据 温湿度转换 4、温湿度转换应用 sht3x初始化 读取温湿度 简介 什么是SHT31? 一主机多从机--通过寻址的方式--每个从机都有唯一的地址&…...
哪款蓝牙耳机打电话好用?打电话音质好的蓝牙耳机
现在几乎是人人离不开耳机的时代。在快节奏的生活和充满嘈杂声音的世界中,戴着耳机听歌,是每个人生活中最不可或缺的一段自由、放松的时光,下面小编就来分享几款通话音质好的蓝牙耳机。 一、南卡小音舱蓝牙耳机 动圈单元:13.3mm…...
【C++】-- 内存泄漏
目录 内存泄漏 内存泄漏分类 如何检测内存泄漏 如何避免内存泄漏 内存泄漏 #问:什么是内存泄漏?内存泄漏:指因为疏忽或错误造成程序未能释放已经不再使用的内存的情况。内存泄漏并不是指内存在物理上的消失,而是应用程序分配某…...
C++ STL学习之【string类的模拟实现】
✨个人主页: Yohifo 🎉所属专栏: C修行之路 🎊每篇一句: 图片来源 The key is to keep company only with people who uplift you, whose presence calls forth your best. 关键是只与那些提升你的人在一起,…...
(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)
题目:3442. 奇偶频次间的最大差值 I 思路 :哈希,时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况,哈希表这里用数组即可实现。 C版本: class Solution { public:int maxDifference(string s) {int a[26]…...
基于FPGA的PID算法学习———实现PID比例控制算法
基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容:参考网站: PID算法控制 PID即:Proportional(比例)、Integral(积分&…...
华为OD机试-食堂供餐-二分法
import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...
DBAPI如何优雅的获取单条数据
API如何优雅的获取单条数据 案例一 对于查询类API,查询的是单条数据,比如根据主键ID查询用户信息,sql如下: select id, name, age from user where id #{id}API默认返回的数据格式是多条的,如下: {&qu…...
爬虫基础学习day2
# 爬虫设计领域 工商:企查查、天眼查短视频:抖音、快手、西瓜 ---> 飞瓜电商:京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空:抓取所有航空公司价格 ---> 去哪儿自媒体:采集自媒体数据进…...
Device Mapper 机制
Device Mapper 机制详解 Device Mapper(简称 DM)是 Linux 内核中的一套通用块设备映射框架,为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程,并配以详细的…...
招商蛇口 | 执笔CID,启幕低密生活新境
作为中国城市生长的力量,招商蛇口以“美好生活承载者”为使命,深耕全球111座城市,以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子,招商蛇口始终与城市发展同频共振,以建筑诠释对土地与生活的…...
人工智能--安全大模型训练计划:基于Fine-tuning + LLM Agent
安全大模型训练计划:基于Fine-tuning LLM Agent 1. 构建高质量安全数据集 目标:为安全大模型创建高质量、去偏、符合伦理的训练数据集,涵盖安全相关任务(如有害内容检测、隐私保护、道德推理等)。 1.1 数据收集 描…...
通过 Ansible 在 Windows 2022 上安装 IIS Web 服务器
拓扑结构 这是一个用于通过 Ansible 部署 IIS Web 服务器的实验室拓扑。 前提条件: 在被管理的节点上安装WinRm 准备一张自签名的证书 开放防火墙入站tcp 5985 5986端口 准备自签名证书 PS C:\Users\azureuser> $cert New-SelfSignedCertificate -DnsName &…...
tauri项目,如何在rust端读取电脑环境变量
如果想在前端通过调用来获取环境变量的值,可以通过标准的依赖: std::env::var(name).ok() 想在前端通过调用来获取,可以写一个command函数: #[tauri::command] pub fn get_env_var(name: String) -> Result<String, Stri…...
