Cookie、Session、Token(JWT)还不懂?

news2024/9/28 21:22:49

Cookie、Session、Token(JWT)

三者的区别与用途!如何进行身份认证,保持用户登录状态?

Cookie、Session 和 Token 都是在 Web 开发中用于管理用户状态和进行身份认证的技术,它们之间有以下区别和用途:

一、Cookie

  1. 含义:Cookie 是存储在用户浏览器中的一小段数据。它由服务器发送到客户端,客户端在后续请求中会将 Cookie 发送回服务器。

  2. 用途:

    • 存储用户偏好设置:例如,用户选择的语言、主题等可以存储在 Cookie 中,以便在用户下次访问时恢复这些设置。

    • 跟踪用户会话:通过设置一个会话 ID 的 Cookie,可以在多个请求之间跟踪用户的会话。

  3. 特点:

    • 存储在客户端:这意味着用户可以查看和修改 Cookie 的内容(虽然通常不建议这样做)。

    • 有大小限制:一般来说,Cookie 的大小不能超过 4KB。

二、Session

  1. 含义:Session 是在服务器端存储的用户会话数据。当用户登录或进行其他需要身份认证的操作时,服务器会创建一个 Session,并为其分配一个唯一的 Session ID。

  2. 用途:

    • 存储用户登录状态:服务器可以在 Session 中存储用户的登录信息,以便在后续请求中验证用户的身份。

    • 保存用户特定的数据:例如,在购物网站中,服务器可以在 Session 中存储用户的购物车内容。

  3. 特点:

    • 存储在服务器端:相比 Cookie,Session 数据更加安全,因为用户无法直接访问和修改服务器端的数据。

    • 依赖 Cookie 或 URL 重写:通常,服务器会通过在 Cookie 中存储 Session ID 来跟踪用户的 Session。如果客户端不支持 Cookie,也可以使用 URL 重写的方式将 Session ID 附加到 URL 中。

    • 占用服务器资源,扩张性差(分布式集群,登录时只存储到了一台服务器,负载均衡时,访问到其他服务器就没有该session显示未登录),依然需要依赖cookie跨域限制

三、Token

  1. 含义:Token 是一种包含用户身份信息的加密字符串。它由服务器生成并发送给客户端,客户端在后续请求中携带 Token 以证明自己的身份。

  2. 用途:

    • 无状态身份认证:Token 可以在无状态的环境中进行身份认证,例如 RESTful API。服务器不需要存储 Session 数据,只需要验证 Token 的有效性即可。

    • 跨域身份认证:Token 可以在不同的域之间进行身份认证,因为它是独立于特定的服务器会话的。

  3. 特点:

    • 自包含:Token 中包含了用户的身份信息,因此服务器不需要在其他地方存储用户的状态。

    • 可扩展性:Token 可以很容易地与第三方服务集成,因为它们不依赖于特定的服务器会话。

四、JWT

JSON Web Token,就是通过JSON来进行传递的加密后字符串。

JSON Web Token(JWT)是一种开放标准(RFC 7519),它定义了一种紧凑且自包含的方式,用于在各方之间安全地传输信息作为 JSON 对象。JWT 由三部分组成,分别用点(.)分隔,这三部分分别是:

一、头部(Header)

  1. 组成内容:通常由两部分组成,令牌的类型(即 “JWT”)和所使用的签名算法,例如 HMAC SHA256 或 RSA。

  2. 示例:{"typ":"JWT","alg":"HS256"}。这表示是一个 JWT,并且使用 HMAC SHA256 算法进行签名。

  3. 编码方式:这个 JSON 对象会使用 Base64Url 编码方式进行编码,生成 JWT 的第一部分。

二、载荷(Payload)

  1. 包含信息:载荷部分包含声明(claims),声明是关于实体(通常是用户)和其他数据的声明。声明有三种类型:注册声明、公开声明和私有声明。

    • 注册声明:预定义的声明,如 “iss”(issuer,签发者)、“exp”(expiration time,过期时间)、“sub”(subject,主题)、“aud”(audience,受众)等。

    • 公开声明:可以由使用 JWT 的各方定义的自定义声明。但为了避免冲突,应该在一个命名空间中定义它们,如 “https://example.com/claims”。

    • 私有声明:在同意使用它们的各方之间共享的自定义声明,通常用于在特定的应用程序上下文中传递特定的信息。

  2. 示例:{"sub":"1234567890","name":"John Doe","admin":true}。在这个例子中,“sub” 是主题,可能是用户的唯一标识符;“name” 是用户的名字;“admin” 是一个自定义的声明,表示用户是否是管理员。

  3. 编码方式:同样使用 Base64Url 编码方式进行编码,生成 JWT 的第二部分。前端也就可以通过截取第二部分信息,通过Base64编码解析获得相关信息

三、签名(Signature)

  1. 生成方式:签名是对头部和载荷的签名,用于验证消息的完整性和真实性,并防止篡改。签名是使用头部(header)中指定的签名算法,对头部和载荷进行签名(自己知道的私钥,通过算法加密)生成的。例如,如果使用 HMAC SHA256 算法,签名是通过将头部和载荷的 Base64Url 编码后的字符串连接起来,使用一个密钥进行 HMAC SHA256 哈希生成的。

  2. 示例:假设使用密钥 “secret” 和 HMAC SHA256 算法,对前面的头部和载荷进行签名,生成的签名可能是 “eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.signature_here” 中的 “signature_here” 部分。

  3. 作用:接收方可以使用相同的密钥和算法对头部和载荷进行签名验证,如果生成的签名与接收到的签名一致,则说明消息没有被篡改。

例如,一个完整的 JWT 可能看起来像这样:

eyJhbGci0iJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtzSI6I1h1c2h1IiwicmVhbG5hbWui0iLlvpDlurYifQ.SBKBBM9fBaBEZ71SbzRxn91xfvtvKq6C-XNezgoZBWw

总之,JWT 的三部分组成提供了一种安全、紧凑的方式来在各方之间传输信息,并且可以通过签名验证消息的完整性和真实性。

五、如何进行身份认证和保持用户登录状态
  1. 使用Cookie:

  • 先发送请求到服务端

  • 服务端响应中set-cookie参数上添加上用户登录信息

  • 在每次请求中携带上cookie信息

  1. 使用 Cookie 和 Session:

  • 用户登录时,服务器验证用户的凭据,如果验证成功,服务器创建一个 Session,并在 Session 中存储用户的登录信息。然后,服务器将 Session ID 作为一个 Cookie 返回给客户端。

  • 在后续请求中,客户端会自动将 Cookie 发送回服务器,服务器通过 Session ID 找到对应的 Session,从而验证用户的身份并获取用户的状态信息。

  • 为了保持用户登录状态,服务器可以设置 Cookie 的过期时间,或者在用户进行某些操作时刷新 Cookie 的过期时间。

  1. 使用 Token:

  • 用户登录时,服务器验证用户的凭据,如果验证成功,服务器生成一个 Token,并将其返回给客户端。

  • 在后续请求中,客户端将 Token 作为一个请求头或参数发送给服务器。服务器验证 Token 的有效性,如果有效,则认为用户已经登录。

  • 为了保持用户登录状态,服务器可以在 Token 中设置过期时间,或者在 Token 即将过期时生成一个新的 Token 并返回给客户端。

例如,在一个基于 Spring Boot 的 Web 应用中,可以使用 Spring Security 来实现基于 Cookie 和 Session 的身份认证,也可以使用 JWT(JSON Web Token)来实现基于 Token 的身份认证。以下是一个使用 JWT 实现身份认证的示例:

 import io.jsonwebtoken.Jwts;
 import io.jsonwebtoken.SignatureAlgorithm;
 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
 import org.springframework.security.core.Authentication;
 import org.springframework.security.core.userdetails.UserDetails;
 import org.springframework.security.core.userdetails.UserDetailsService;
 import org.springframework.web.filter.OncePerRequestFilter;
 ​
 import javax.servlet.FilterChain;
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
 import java.util.Date;
 ​
 public class JwtAuthenticationFilter extends OncePerRequestFilter {
 ​
     private final UserDetailsService userDetailsService;
     private final String secret;
 ​
     public JwtAuthenticationFilter(UserDetailsService userDetailsService, String secret) {
         this.userDetailsService = userDetailsService;
         this.secret = secret;
     }
 ​
     @Override
     protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
             throws ServletException, IOException {
 ​
         String token = getTokenFromRequest(request);
         if (token!= null &&!token.isEmpty()) {
             try {
                 String username = Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody().getSubject();
                 UserDetails userDetails = userDetailsService.loadUserByUsername(username);
                 Authentication authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
                 SecurityContextHolder.getContext().setAuthentication(authentication);
             } catch (Exception e) {
                 // Token 无效,不进行身份认证
             }
         }
 ​
         filterChain.doFilter(request, response);
     }
 ​
     private String getTokenFromRequest(HttpServletRequest request) {
         String bearerToken = request.getHeader("Authorization");
         if (bearerToken!= null && bearerToken.startsWith("Bearer ")) {
             return bearerToken.substring(7);
         }
         return null;
     }
 ​
     public String generateToken(String username) {
         Date expirationDate = new Date(System.currentTimeMillis() + 86400000); // 1 day expiration
         return Jwts.builder()
                .setSubject(username)
                .setExpiration(expirationDate)
                .signWith(SignatureAlgorithm.HS512, secret)
                .compact();
     }
 }

在这个示例中,JwtAuthenticationFilter类实现了一个 Spring Security 的过滤器,用于从请求中提取 JWT Token,并进行身份认证。如果 Token 有效,过滤器会创建一个Authentication对象,并将其设置到SecurityContextHolder中,以便后续的请求可以获取用户的身份信息。

总之,Cookie、Session 和 Token 都有各自的特点和用途,可以根据具体的应用场景选择合适的技术来进行身份认证和保持用户登录状态。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【js逆向学习】酷我音乐排行榜 python+nodejs(webpack)

逆向目标 目标网址: https://www.kuwo.cn/rankList目标接口: https://www.kuwo.cn/api/www/bang/bang/musicList 加密参数: 参数一:secret参数二:reqId 逆向过程 老规矩先分析网络请求,我们可以分析到网络请求是通过ajax进行的&#xff…

【C++】C/C++内存管理(new/delete)

C/C内存分布 代码内存相关问题 int globalVar 1; static int staticGlobalVar 1;void Test() {static int staticVar 1;int localVar 1;int num1[10] { 1, 2, 3, 4 };char char2[] "abcd";const char* pChar3 "abcd";int* ptr1 (int*)malloc(siz…

yolox训练自己的数据集

环境搭建 gpu按自己情况安装 nvidia-smi 查看自己的版本 CUDA和cudnn 按自己的安装,我的驱动551.76,注意不要用最新的,官网只要求驱动是大于等于,可以用低版本的cuda,我安装的是CUDA 11.1 cuda下载后&#xff0c…

报告查询系统小程序开发制作方案

报告查询小程序系统主要是为了解决传统报告查询方式往往依赖于纸质文档或复杂的内网系统,存在查询效率低、信息更新慢、携带不便等问题。 一、目标用户 企业员工:需要频繁查询各类工作报告,如销售人员查询销售业绩报告,财务人员查…

信道衰落的公式

对于天线: 对于天线的面积计算: 天线的接收功率密度: 天线的接收功率: 移动无线信道(I) (xidian.edu.cn)https://web.xidian.edu.cn/zma/files/20150710_153736.pdf 更加常用的考虑了额外的信道衰落pathlo…

基于YOLOv5的农作物病虫害识别系统设计与实现(PYQT+web端+微信小程序+YOLOv5+训练数据集+论文+部署文档+开题报告)

摘要 农作物病虫害是农业生产中的关键问题,病虫害的爆发和侵袭不仅严重影响农作物产量和质量,还可引发局部地区严重的灾害性损失。因此,及时发现和预防农作物病虫害的发生和发展至关重要。本文以农作物病虫害图像为载体,运用深度…

python的高级用法

对于python的使用,我们常见的用法是python xx.py直接执行脚本,有时可能您需要在脚本的第一行添加(#!/usr/bin/env python3 或 #!/usr/local/bin/python3),然后chmod确保脚本文件具有可执行权限。这样脚本就可以在终端直…

从哪里下载高清解压视频素材?推荐五个优质素材资源网站

想制作吸引人的抖音小说推文,但不知道从哪里获取高清解压视频素材?今天就为大家推荐五个优秀的网站,帮助你轻松找到所需的素材,提升你的创作质量。 首先是蛙学网 作为国内顶级的短视频素材网站,蛙学网提供了丰富的4K高…

Vxe UI vue 使用 vxe-tabs 页签实现右侧操作按钮、关闭所有页签、关闭右侧、关闭左侧

Vxe UI vue 使用 vxe-tabs 页签实现右侧操作按钮、关闭所有页签、关闭右侧、关闭左侧 查看 github <template><div><vxe-tabs v-model"selectTab" :options"tabList"><template #extra><vxe-pulldown :options"tabOptio…

Flood Fill模型

这个模型主要用来求连通块的数量&#xff0c;在求连通块时有“8连通”和“4连通”之分。 看上面的图形&#xff0c;如果是4连通那么红色和绿色就不连通&#xff08;只有一个格子的“上下左右”相连才叫连通&#xff09;。如果是8连通那就联通&#xff08;不仅仅包含边相连&…

SwiftUI简明概念(4):如何对shape同时进行fill和stroke

1、iOS17方案 iOS17上可以同时对shape调用fill和stroke&#xff1a; Circle().stroke(.red, lineWidth: 20).fill(.orange).frame(width: 150, height: 150) 效果也如我们所预料的&#xff1a; 而且stroke可以调用任意次&#xff1a; Circle().stroke(.blue, lineWidth: 45…

【路径规划】基于球向量的粒子群优化(SPSO)算法在无人机路径规划中的实现

摘要 本文介绍了基于球形矢量的粒子群优化&#xff08;Spherical Particle Swarm Optimization, SPSO&#xff09;算法&#xff0c;用于无人机&#xff08;UAV&#xff09;路径规划。SPSO算法通过引入球形矢量的概念&#xff0c;增强了粒子群在多维空间中的探索和利用能力&…

TXT文档批量处理,根据总行数平均分成多个文件保存,批量拆分实例分享

在高强度的工作下&#xff0c;怎样拆分文档&#xff0c;手动拆分整理&#xff0c;不仅效率低&#xff0c;而且还容易出错。当然是要选择操作轻松简单首助编辑高手&#xff0c;提高工作效率。 1、打开软件并选择到文本批量操作功能选项上&#xff0c;选择文本批量操作&#xff1…

【C++】类和对象(类的定义,类域,实例化,this指针)

目录 一. 类的定义 【对比c】结构体和类的区别 1. 称呼&#xff1a;变量 or 对象&#xff1f; 2. 类型&#xff1a; 3. 访问限定&#xff1a; 4. c和c结构体使用 5. 相同点&#xff1a; 二. 类域 三. 实例化 1. 1对N 2. 计算大小只考虑成员变量 3. 到此一游 四. …

一、前后端分离及drf的概念

1.1什么是前后端分离 程序角度 前后端不分离&#xff1a;一个程序&#xff08;如django),接收请求处理HTML模版用户返回 前后端分离&#xff1a;两个程序 --前端&#xff1a;vue.js/react.js/angular.js --后端&#xff1a;Django drf(django rest framework) 2.专业角度 --…

3.消息机制总结——总结

Handler 机制的底层逻辑就是利用 epoll eventfdAndroid2.3开始 Google把Handler的阻塞/唤醒方案从Object#wait()/notify(),改为Linux epoll实现&#xff0c;why&#xff1f;原因在于&#xff0c;native也引入了消息管理机制&#xff0c;用于提供个C/C开发者使用&#xff0c;而…

nicegui组件button用法深度解读,源代码IDE运行和调试通过

传奇开心果微博文系列 前言一、button 组件基本用法1. 最基本用法示例2. 创建带图标按钮 二、button按钮组件样式定制1. 按钮的尺寸调整2. 改变颜色示例3. 按钮的自定义字体大小4. 圆角形状示例5. 自定义边框6. 添加阴影7. 复合按钮8. 浮动按钮9. 可扩展浮动操作按钮QFAB10. 按…

使用k8s部署java前后端服务

一、项目架构 前端、后端、数据库 1&#xff09;前端 静态的资源&#xff1a;img css html js文件 js&#xff1a;axios、ajax 2&#xff09;后端 提供数据&#xff1a;根据web前端发送的请求&#xff0c;从数据库中获取数据 请求都是无状态的&#xff0c;如何保持会话 …

依赖注入之set注入

set注入 set注入&#xff0c;基于set王法实现的&#xff0c;底层通过反射机制调用属性对应的set方法&#xff0c;然后给属性赋值&#xff0c;这种方法要求属性必须对外提供set方法 1. 想让Spring调用对应的set方法&#xff0c;需要配置property标签 2. name属性怎么指定值:s…

【含文档】基于Springboot+微信小程序 的高中信息技术课程在线测试系统(含源码+数据库+lw)

1.开发环境 开发系统:Windows10/11 架构模式:MVC/前后端分离 JDK版本: Java JDK1.8 开发工具:IDEA 数据库版本: mysql5.7或8.0 数据库可视化工具: navicat 服务器: SpringBoot自带 apache tomcat 主要技术: Java,Springboot,mybatis,mysql,vue 2.视频演示地址 3.功能 当游客…