JWT学习笔记

了解 JWT Token 释义及使用 | Authing 文档

JSON Web Token Introduction - jwt.io

JSON Web Token (JWT,RFC 7519 (opens new window)),是为了在网络应用环境间传递声明而执行的一种基于 JSON 的开放标准((RFC 7519)。该 token 被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO)场景。JWT 的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也可以增加一些额外的其它业务逻辑所必须的声明信息,该 token 也可直接被用于认证,也可被加密。

1. 认证

传统的Session认证方式需要在服务器端存储用户登录信息,通常而言session都是保存在内存中,而随着认证用户的增多,服务端的开销会明显增大。基于Token的认证方式不需要在服务端去保留用户的认证信息或者会话信息。

流程上是这样的:

  • 用户使用用户名密码来请求服务器
  • 服务器进行验证用户的信息
  • 服务器通过验证发送给用户一个token
  • 客户端存储token,并在每次请求时附送上这个token值
  • 服务端验证token值,并返回数据

2. JWT的结构

它采用缩写的形式,包含三个部分,由.分割,包括以下三个部分

  • Header——头部
  • Payload——有效荷载
  • Signature——签名

因此JWT呈现为这种形式:

xxxxx.yyyyy.zzzzz

2.1. Header

头部包含两个部分:(1)token的类型,即JWT;(2)使用的签名算法,如HMAC、SHA256或RSA

例如:

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

2.2. Payload

该部分包含一些实体和数据的声明,如用户等,包括已注册声明、公开声明、私有声明三类。

例如:

{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true
}

2.3. Signature

要创建签名部分,您必须获取编码的标头、编码的有效负载、密钥、标头中指定的算法,然后对其进行签名。

3. 使用

jjwt10:GitHub - jwtk/jjwt: Java JWT: JSON Web Token for Java and Android

目前jjwt10以上版本和jjwt9使用方法不同,好像使用jjwt9还是偏多一些。

jjwt9:jjwt 0.9.1 javadoc (io.jsonwebtoken)

以下代码是从mall项目中学习的JWT的工具类,一般可作为模板使用,主要提供了生成token和解析token的API,使用的是jjwt9

@Component
public class JwtTokenUtil {
    private static final Logger LOGGER = LoggerFactory.getLogger(JwtTokenUtil.class);

    //sub: subject,主体,即登录的主体,一般是用户名
    private static final String CLAIM_KEY_USERNAME = "sub";

    //created表示创建时间
    private static final String CLAIM_KEY_CREATED = "created";
    @Value("${jwt.secret}")
    private String secret;
    @Value("${jwt.expiration}")
    private Long expiration;

    /**
     * 根据负载生成JWT的token
     * @param claims 声明,即JWT中的payload部分
     * @return token:String
     */
    private String generateToken(Map<String, Object> claims) {
        return Jwts.builder()   //生成一个DefaultJwtBuilder类实例
                .setClaims(claims)      //设置该DefaultJwtBuilder类实例的claims字段
                .setExpiration(generateExpirationDate())    //设置过期时间
                .signWith(SignatureAlgorithm.HS512, secret) //设置签名算法、密钥
                .compact();     //调用compact函数才能生成JWT
    }

    /**
     * 从token中获取JWT中的负载
     * @param token
     * @return Claims类实例
     */
    private Claims getClaimsFromToken(String token) {
        Claims claims = null;
        try {
            claims = Jwts.parser()
                    .setSigningKey(secret)
                    .parseClaimsJws(token)
                    .getBody();
        } catch (Exception e) {
            LOGGER.info("JWT格式验证失败:{}",token);
        }
        return claims;
    }

    /**
     * 根据expiration生成token的过期时间
     * @return Date
     */
    private Date generateExpirationDate() {
        return new Date(System.currentTimeMillis() + expiration * 1000);
    }

    /**
     * 从token中获取登录用户名
     */
    public String getUserNameFromToken(String token) {
        String username;
        try {
            Claims claims = getClaimsFromToken(token);
            username =  claims.getSubject();
        } catch (Exception e) {
            username = null;
        }
        return username;
    }

    /**
     * 验证token是否还有效
     *
     * @param token       客户端传入的token
     * @param userDetails 从数据库中查询出来的用户信息
     */
    public boolean validateToken(String token, UserDetails userDetails) {
        String username = getUserNameFromToken(token);
        return username.equals(userDetails.getUsername()) && !isTokenExpired(token);
    }

    /**
     * 判断token是否已经失效
     */
    private boolean isTokenExpired(String token) {
        Date expiredDate = getExpiredDateFromToken(token);
        return expiredDate.before(new Date());
    }

    /**
     * 从token中获取过期时间
     */
    private Date getExpiredDateFromToken(String token) {
        Claims claims = getClaimsFromToken(token);
        return claims.getExpiration();
    }

    /**
     * 根据用户信息生成token
     * @param userDetails UserDetails类实例
     * @return token
     */
    public String generateToken(UserDetails userDetails) {
        Map<String, Object> claims = new HashMap<>();
        claims.put(CLAIM_KEY_USERNAME, userDetails.getUsername());
        claims.put(CLAIM_KEY_CREATED, new Date());
        return generateToken(claims);
    }
}

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

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

相关文章

微服务基础环境搭建

一.创建父工程 用于聚合其他微服务模块 1 新建 Maven 项目 JDK8Maven 项目Web 2 项目设置 编码的选择 UTF8JDK 版本的选择 3 删除 src 目录 4 配置父级 pom.xml SpringBoot&#xff1a;模块探究之spring-boot-dependencies-CSDN博客 子模块能够依赖当前父级 pom.xml 配置 【My…

数据结构-Queue队列

一,队列的简单认识 队列也是一种线性数据结构,与栈不同的是,它只能从一端添加元素,从另一端取出元素.定义了一端,另一端也就确定了. (当然还有一个特殊的双向队列LinkedList除外,它既可以从队首添加元素,也可以移除元素,队尾也是一样的,既可以添加元素,也可以移除元素) 二,队…

有哪些副业渠道?

夸克网盘这个软件出来好久了&#xff0c;官方前不久才开通了推广渠道&#xff0c;这就给了我们以此赚钱的机会。具体时间应该是在2022年12月份。 所谓夸克网盘拉新&#xff0c;就是夸克网盘为了抢占市场&#xff0c;与其他网盘竞争对手&#xff08;百度网盘、迅雷网盘等&#…

一键生成请求方法的工具 —— OpenAPI Typescript Codegen

文章目录 用法自定义请求参数的方法1&#xff09;使用代码生成器提供的全局参数修改对象2&#xff09;直接定义 axios 请求库的全局参数&#xff0c;比如&#xff1a;全局请求响应拦截器 报错解决 用法 首先下载axios npm install axios官网&#xff1a;https://github.com/f…

Centos中安装Docker及Docker的使用

在centos7系统中安装指定版本的docker,并通过docker使用安装mysql为例,阐述docker的使用。 2.1、Docker卸载及安装yum依赖 【卸载Docker,如果安装的Docker的版本不合适】 yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-…

Kafka之Producer源码

Producer源码解读 在 Kafka 中, 我们把产生消息的一方称为 Producer 即 生产者, 它是 Kafka 的核心组件之一, 也是消息的来源所在。它的主要功能是将客户端的请求打包封装发送到 kafka 集群的某个 Topic 的某个分区上。那么这些生产者产生的消息是怎么传到 Kafka 服务端的呢&a…

常用路径规划算法简介及python程序

目录 1、前言2、D*算法2.1简介2.2优缺点2.2.1 优点2.2.2 缺点 2.3 python程序 3、A*算法3.1 优缺点&#xff1a;3.1.1 优点&#xff1a;3.1.2 缺点&#xff1a; 3.2 python程序 4、人工势场算法4.1优缺点4.1.1优点&#xff1a;4.1.2缺点&#xff1a; 4.2 python程序 5、Dijkstr…

BeautifulSoup+xpath+re+css简单复习+新的scrapy的学习

1.BeautifulSoupsoup BeautifulSoup(html,html.parser)all_icosoup.find(class_"DivTable") 2.xpath trs resp.xpath("//tbody[idcpdata]/tr") hong tr.xpath("./td[classchartball01 or classchartball20]/text()").extract() 这个意思是找…

今日早报 每日精选15条新闻简报 每天一分钟 知晓天下事 2月26日,星期一

每天一分钟&#xff0c;知晓天下事&#xff01; 2024年2月26日 星期一 农历正月十七 1、 气象台&#xff1a;3月初之前南方大部将维持阴雨雪天气。 2、 据海关统计&#xff0c;京津冀协同发展十年成效显著&#xff0c;外贸总量跨两个万亿台阶。 3、 2024年研考初试成绩今天起…

【数据库】MySQL视图 | 用户管理

文章目录 1 :peach:视图:peach:1.1 :apple:基本使用:apple:1.1.1 :lemon:创建视图:lemon:1.1.2 :lemon:案例:lemon:1.1.3 :lemon:删除视图:lemon: 1.2 :apple:视图规则和限制:apple: 2 :peach:用户管理:peach:2.1 :apple:用户信息:apple:2.2 :apple:创建用户:apple:2.3 :apple:…

国企行政题库--校园招聘

国企行政题库是为准备参加国有企业行政类岗位校园招聘的应聘者提供的一套专门准备的试题资料。国有企业在中国经济中扮演着重要的角色&#xff0c;其行政类岗位需求量大&#xff0c;竞争激烈。通过系统学习和准备国企行政题库&#xff0c;将有助于应聘者更好地了解国企行政类岗…

解析OOM的三大场景,原因及实战解决方案

目录 一、什么是OOM 二、堆内存溢出&#xff08;Heap OOM&#xff09; 三、方法区内存溢出&#xff08;Metaspace OOM&#xff09; 四、栈内存溢出&#xff08;Stack OOM&#xff09; 一、什么是OOM OOM 是 Out Of Memory 的缩写&#xff0c;意思是内存耗尽。在计算机领域…

Centos服务器部署前后端项目

目录 准备工作1. 准备传输软件2. 连接服务器 部署Mysql1.下载Mysql(Linux版本)2. 解压3. 修改配置4. 启动服务另一种方法Docker 部署后端1. 在项目根目录中创建Dockerfile文件写入2. 启动 部署前端1. 在项目根目录中创建Dockerfile文件写入2. 启动 准备工作 1. 准备传输软件 …

QEMU源码全解析 —— virtio(24)

接前一篇文章&#xff1a; 上回书讲解了virtioballoon_probe函数及其中的两个重要函数init_vqs()和virtio_device_ready()&#xff0c;解析了init_vqs函数的前两步&#xff0c;本回继续解析该函数&#xff0c; &#xff08;3&#xff09;init_vqs函数在经过了对于各feature的初…

【电机仿真】HFI算法脉振高频电压信号注入观测器-PMSM无感FOC控制

【电机仿真】HFI算法脉振高频电压信号注入观测器-PMSM无感FOC控制 文章目录 前言一、脉振高频电压注入法简介&#xff08;注入在旋转坐标系的d轴&#xff09;1.旋转高频电压&#xff08;电流&#xff09;注入法2.脉振高频电压注入法 二、高频注入理论1.永磁同步电机的高频模型2…

EasyRecovery2024个人免费版本电脑手机数据恢复软件下载

EasyRecovery是一款功能强大的数据恢复软件&#xff0c;能够帮助用户恢复丢失、删除、格式化或损坏的数据。无论是由于误操作、病毒攻击、硬盘故障还是其他原因导致的数据丢失&#xff0c;EasyRecovery都能提供有效的解决方案。 该软件支持从各种存储介质恢复数据&#xff0c;…

springboot215基于springboot技术的美食烹饪互动平台的设计与实现

美食烹饪互动平台的设计与实现 摘 要 如今社会上各行各业&#xff0c;都喜欢用自己行业的专属软件工作&#xff0c;互联网发展到这个时候&#xff0c;人们已经发现离不开了互联网。新技术的产生&#xff0c;往往能解决一些老技术的弊端问题。因为传统美食信息管理难度大&…

密码安全+破解+防御

一步一脚印&#xff01; 目录 密码安全简介 密码猜解思路 字典生成 crunch工具(kali自带) 社工生成字典(safe6pwd)&#xff1a; python代码实现暴力破解 burpsuite爆破 验证码自动识别 hydra爆破ssh密码 hydra工具 medusa爆破ssh密码 medusa工具 msf爆破ssh密码 …

基于YOLOv8深度学习+Pyqt5的电动车头盔佩戴检测系统

wx供重浩&#xff1a;创享日记 对话框发送&#xff1a;225头盔 获取完整源码源文件已标注的数据集&#xff08;1463张&#xff09;源码各文件说明配置跑通说明文档 若需要一对一远程操作在你电脑跑通&#xff0c;有偿89yuan 效果展示 基于YOLOv8深度学习PyQT5的电动车头盔佩戴检…

Open3D 基于最小生成树的法线定向 (27)

Open3D 基于最小生成树的法线定向 (27) 一、算法介绍二、算法实现一、算法介绍 法线计算的方向通常都存在方向问题,用Open3D估计的点云法线,是在每个点的局部进行拟合,估计的法线方向并不一致,Open3D提供了使用最小生成树调整法线到统一方向的方法,下面是具体的实现代码…