JWT令牌——详解

news2024/9/20 7:50:05

目录

一、JWT是什么?

二、JWT的组成

三、JWT应用场景

四、生成和校验JWT令牌

五、具体应用


 

一、JWT是什么?

        在当今的Web开发中,安全认证和授权变得尤为重要。JWT(JSON Web Tokens)是一种开放标准(RFC 7519),它定义了一种简洁、紧凑且自包含的方式,用于在各方之间安全地传输信息。这种信息可以被验证和信任,但不需要依赖服务器来解析。

        JWT全称:JSON Web Token (官网:JSON Web Tokens - jwt.ioJSON Web Tokens - jwt.ioJSON Web Tokens - jwt.io)      

  • 简洁:是指jwt就是一个简单的字符串。可以在请求参数或者是请求头当中直接传递。
  • 紧凑:指的是它能够以较小的体积包含所有的信息。JWT使用Base64Url编码算法JWT支持多种加密算法,如HS256、RS256等,这些算法能够在保证安全性的同时,保持令牌的大小不会过大。
  • 自包含:指的是jwt令牌,看似是一个随机的字符串,但是我们是可以根据自身的需求在jwt令牌中存储自定义的数据内容。JWT包含了所有必要的信息来验证其有效性,不需要额外的查询或数据库操作。如:可以直接在jwt令牌中存储用户的相关信息。

        简单来讲,jwt就是将原始的json数据格式进行了安全的封装,这样就可以直接基于jwt在通信双方安全的进行信息传输了。

二、JWT的组成

        JWT由三部分组成:头部(Header)、载荷(Payload)和签名(Signature)用.分隔。这三部分以.分隔,形如xxxxx.yyyyy.zzzzz

  假设我们有一个JWT如下:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

头部(Header):包含了令牌的类型和所使用的加密算法。

  • 编码后:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
  • 解码后:
    {
      "alg": "HS256",
      "typ": "JWT"
    }
    头部告诉我们签名算法(HS256)和令牌类型(JWT)

载荷(Payload):存放实际的数据,可以是任何形式的JSON对象。

  • 编码后:eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ
  • 解码后:
    {
      "name": "John Doe",
      "admin": true,
      "roles": ["user", "admin"],
      "exp": 1687016741
    }

    载荷包含了声明信息,如用户姓名、是否为管理员、用户角色和过期时间。

签名(Signature):用于验证令牌的发送者和内容是否被篡改。签名由头部、载荷、秘钥和指定的算法生成。       

  • SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
  • 签名是对头部和载荷的加密,确保令牌的完整性和可靠性。

        在生成JWT令牌时,会对JSON格式的数据进行一次编码:进行base64编码

        Base64:是一种基于64个可打印的字符来表示二进制数据的编码方式。既然能编码,那也就意味着也能解码。所使用的64个字符分别是A到Z、a到z、 0- 9,一个加号,一个斜杠,加起来就是64个字符。任何数据经过base64编码之后,最终就会通过这64个字符来表示。当然还有一个符号,那就是等号。等号它是一个补位的符号。需要注意的是Base64是编码方式,而不是加密方式。

三、JWT应用场景

        JWT令牌最典型的应用场景就是登录认证:

 

  1. 客户端请求认证:用户通过用户名和密码请求登录。
  2. 服务器验证请求:服务器验证用户凭证,如果有效,生成JWT。
  3. 客户端存储令牌:客户端接收到JWT后,存储在本地(通常是LocalStorage或SessionStorage)。
  4. 客户端发送令牌:之后的每个请求都带有这个JWT,通常放在HTTP头的Authorization字段中。
  5. 服务器验证令牌:服务器验证JWT的有效性,如果有效则处理请求,否则拒绝。

四、生成和校验JWT令牌

要想使用JWT令牌,需要先引入JWT的依赖:

<!-- JWT依赖-->
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.1</version>
</dependency>

在引入完JWT来赖后,就可以调用工具包中提供的API来完成JWT令牌的生成和校验。

生成JWT代码实现:

@Test
public void genJwt(){
    Map<String,Object> claims = new HashMap<>();
    claims.put("id",1);
    claims.put("username","Tom");
    
    String jwt = Jwts.builder()
        .setClaims(claims) //自定义内容(载荷)          
        .signWith(SignatureAlgorithm.HS256, "itheima") //签名算法        
        .setExpiration(new Date(System.currentTimeMillis() + 24*3600*1000)) //有效期一天   
        .compact();//将JWT转换为一个紧凑的字符串形式
    
    System.out.println(jwt);
}

       运行测试方法,输出的结果就是生成的JWT令牌,,通过英文的点分割对三个部分进行分割,我们可以将生成的令牌复制一下,然后打开JWT的官网,将生成的令牌直接放在Encoded位置,此时就会自动的将令牌解析出来。   

        前两个部分是base64编码,所以是可以直接解码出来。但最后一个部分并不是base64编码,是经过签名算法计算出来的,所以最后一个部分是不会解析的。

        实现了JWT令牌的生成,下面我们接着使用Java代码来校验JWT令牌(解析生成的令牌):

@Test//单元测试注解
public void parseJwt(){
    Claims claims = Jwts.parser()
        .setSigningKey("itheima")//指定签名密钥(必须保证和生成令牌时使用相同的签名密钥)  
	    .parseClaimsJws("eyJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjcyNzI5NzMwfQ.fHi0Ub8npbyt71UqLXDdLyipptLgxBUg_mSuGJtXtBk")
        .getBody();//获取的是第二部分

    System.out.println(claims);
}

         篡改令牌中的任何一个字符,在对令牌进行解析时都会报错,所以JWT令牌是非常安全可靠的。JWT令牌过期后,令牌就失效了,解析的为非法令牌。 JWT校验时使用的签名秘钥,必须和生成JWT令牌时使用的秘钥是配套的。

五、具体应用

        在项目工程下创建utils包,创建JWT工具类(生成令牌+解析令牌)

public class JwtUtils {

    private static String signKey = "itheima";//签名密钥
    private static Long expire = 43200000L; //有效时间

    /**
     * 生成JWT令牌
     * @param claims JWT第二部分负载 payload 中存储的内容
     * @return
     */
    public static String generateJwt(Map<String, Object> claims){
        String jwt = Jwts.builder()
                .addClaims(claims)//自定义信息(有效载荷)
                .signWith(SignatureAlgorithm.HS256, signKey)//签名算法(头部)
                .setExpiration(new Date(System.currentTimeMillis() + expire))//过期时间
                .compact();
        return jwt;
    }

    /**
     * 解析JWT令牌
     * @param jwt JWT令牌
     * @return JWT第二部分负载 payload 中存储的内容
     */
    public static Claims parseJWT(String jwt){
        Claims claims = Jwts.parser()
                .setSigningKey(signKey)//指定签名密钥
                .parseClaimsJws(jwt)//指定令牌Token
                .getBody();
        return claims;
    }
}

        登录完成后,调用工具类生成JWT令牌并返回  

@RestController
@Slf4j
public class LoginController {
    //依赖业务层对象
    @Autowired
    private EmpService empService;

    @PostMapping("/login")
    public Result login(@RequestBody Emp emp) {
        //调用业务层:登录功能
        Emp loginEmp = empService.login(emp);

        //判断:登录用户是否存在
        if(loginEmp !=null ){
            //自定义信息
            Map<String , Object> claims = new HashMap<>();
            claims.put("id", loginEmp.getId());
            claims.put("username",loginEmp.getUsername());
            claims.put("name",loginEmp.getName());

            //使用JWT工具类,生成身份令牌
            String token = JwtUtils.generateJwt(claims);
            return Result.success(token);
        }
        return Result.error("用户名或密码错误");
    }
}

        登录请求完成后,可以看到JWT令牌已经响应给了前端。

        在后续的请求当中,都会在请求头中携带JWT令牌到服务端,而服务端需要统一拦截所有的请求,从而判断是否携带的有合法的JWT令牌。那怎么样来统一拦截到所有的请求校验令牌的有效性呢?这里我们会用到两种解决方案:Filter过滤器和Interceptor拦截器。


        JWT虽然提供了一种简洁、安全的认证方式,但也有一些注意事项,如令牌的有效期设置、敏感信息的存储等。在使用JWT时,应结合具体的应用场景和需求进行合理的设计和配置。总之,JWT是现代Web应用中一个非常有用的工具,它简化了认证流程,提高了应用的安全性和可扩展性。通过理解其原理和正确的使用方法,你可以有效地保护你的应用和用户数据。

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

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

相关文章

大厂中秋福利哪家强?字节发被子,京东联名三星堆!网友:最强的还是我们......

又是一年中秋佳节&#xff0c;大家公司发的中秋福利都拿到手了嘛&#xff1f; 从上周开始&#xff0c;各社交网络平台上就有人陆续晒出了公司发放的中秋礼盒。 其中&#xff0c;财大气粗的互联网大厂的礼盒尤为精致亮眼。 今天&#xff0c;小码就带大家一起来看看大厂那些让人…

在线机房迁移之“玩转TiDB迁移”

作者&#xff1a; 代晓磊_Mars 原文来源&#xff1a; https://tidb.net/blog/02df4029 要想搞定在线机房迁移之TiDB数据库迁移&#xff0c;看完本文基本上所有的迁移方案你都可以搞定了&#xff08;数据库迁移方案和流程大同小异&#xff09;。本文给了3种TiDB在线迁移的场景…

四款音频剪辑软件免费使用,你更pick哪一个?

视频剪辑知随着软件的不断更新&#xff0c;入门门槛和操作难度也随之变得越来越低&#xff0c;但是依然有不少人不知道剪辑视频要用什么工具&#xff0c;作为一个视频剪辑爱好者&#xff0c;我尝试过不少编辑软件&#xff0c;今天就来跟大家分享一下四款视频剪辑软件在实际使用…

我与Linux的爱恋:yum和vim以及gcc、gdb、git的使用

​ ​ &#x1f525;个人主页&#xff1a;guoguoqiang. &#x1f525;专栏&#xff1a;Linux的学习 文章目录 ​1.Linux软件包管理器yum2.Linux开发工具3.Linux编译器 vimvim的基本概念vim的基本操作vim正常模式命令集vim末行模式命令集vim操作总结批量化注释批量化去注释简…

Oracle反向键索引Reverse Key Index

Oracle反向键索引&#xff08;Reverse Key Index&#xff09;是一种特殊的B-Tree索引&#xff0c;它在创建索引时对索引列的键值进行字节反转。这种索引的主要设计目的是为了解决在多实例环境&#xff08;如Oracle RAC&#xff09;中由于索引键值顺序插入导致的索引块争用问题。…

Vue 3 watchEffect:如何用 onInvalidate 优化副作用处理

在 Vue3 中&#xff0c;watchEffect 是一个用于在响应式数据变化时自动重新执行的函数。它在创建响应式副作用时特别有用&#xff0c;比如在某些数据变化时更新 DOM、发起网络请求或处理复杂的逻辑。 watchEffect 的 onInvalidate 是一个非常重要的功能&#xff0c;用于处理副…

新闻资讯类APP流量变现技巧——提升广告变现收益

新闻资讯类APP拥有庞大的用户基础&#xff0c;始终拥有较强的广告变现能力&#xff0c;如何在激烈的行业竞争中凸显媒体的优势&#xff0c;进而吸引更多的广告主&#xff1f;优化核心场景广告样式的同时&#xff0c;挖掘更多的广告场景样式&#xff1f;如何把握好广告变现和用户…

“Interface 和 Type 区别”深度解析

“Interface 和 Type 区别”深度解析 文章目录 一、Interface 和 Type 是什么二、如何使用 Interface 和 Type1. 定义 Interface2. 定义 Type3. 使用 Interface 和 Type4. 区别与联系 三、Interface 和 Type 二者有哪些区别&#xff0c;分别在哪些场景使用1. 区别2. 场景 四、扩…

将Ruoyi框架系统的Swagger接口文档页面优化为knife4j风格

将Swagger文档原来的页面效果改成比较好看的knife4j风格文档页面 优化前&#xff1a; 请求地址&#xff1a;http://localhost:端口号/swagger-ui/index.html 优化后&#xff1a; 请求地址&#xff1a;http://localhost:端口号/doc.html#/home 修改步骤&#xff1a; 1.引入依…

CPU调度算法之优先级调度

点击下载《CPU调度算法之优先级调度》 摘要 CPU的优先级调度算法是一种通过为不同任务分配优先级来决定执行顺序的调度策略。这种算法使得系统能够优先处理那些被认为更重要或紧急的任务&#xff0c;从而提高整体效率和响应速度。然而&#xff0c;优先级调度也可能带来一些问…

快速求和

请编写程序&#xff0c;输入整数 n&#xff0c;快速计算&#xff1a; 输入格式 n 输出格式 s 要求&#xff1a;输出 6 位小数&#xff0c;末位四舍五入。 代码如下&#xff1a; #include<stdio.h> int main(){int n;double s;scanf("%d",&n);s1.0-1.0/(n1…

DeepACO:用于组合优化的神经增强蚂蚁系统

文章目录 Abstract1 Introduction2 Related work2.1 神经组合优化2.2 蚁群优化3 蚁群优化初探4 Methodology4.1 参数化启发式空间4.2 局部搜索与局部神经引导扰动交织4.3 训练启发式学习器4.4 更好的探索4.4.1 多头解码器4.4.2 Top-k熵损失4.4.3 模仿损失5 实验5.1 实验设置5.2…

DWS=管理员用户创建

管理员用户简介 管理员也称作系统管理员&#xff0c;是指具有SYSADMIN属性的帐户。 非三权分立模式下&#xff0c;拥有系统的最高权限&#xff0c;能够执行所有的操作。系统管理员具有与对象所有者相同的权限。管理员用户创建 su - omm source /opt/huawei/Bigdata/mppdb/.mpp…

【数据结构-二维前缀最小值】力扣3148. 矩阵中的最大得分

给你一个由 正整数 组成、大小为 m x n 的矩阵 grid。你可以从矩阵中的任一单元格移动到另一个位于正下方或正右侧的任意单元格&#xff08;不必相邻&#xff09;。从值为 c1 的单元格移动到值为 c2 的单元格的得分为 c2 - c1 。 你可以从 任一 单元格开始&#xff0c;并且必须…

2024年汉字小达人校内选拔的常见问题和解答

广受上海市小学生们关注的2024年第十一届汉字小达人的时间已经确定了&#xff0c;参赛的孩子们已经开始紧锣密鼓的准备中。 如昨天分析的2024年汉字小达人的赛程&#xff0c;即日起到10月20日是学校自行选拔的时间节点。9月25-30日是区级自由报名集中参赛的日子。两个日子有一…

中秋佳节,如何挑选实用有意义的礼物?精选中秋节最佳送礼清单!

当秋风送爽&#xff0c;丹桂飘香&#xff0c;我们即将迎来一年一度的中秋佳节。在这个充满温情与团圆的节日里&#xff0c;赠送礼物成为了表达我们对家人、朋友以及同事的关怀与祝福的重要方式。然而&#xff0c;面对琳琅满目的商品&#xff0c;如何挑选出既实用又有意义的礼物…

《现代食品》是什么级别的期刊?是正规期刊吗?能评职称吗?

​问题解答 问&#xff1a;《现代食品》是不是核心期刊&#xff1f; 答&#xff1a;不是&#xff0c;是知网收录的正规学术期刊。 问&#xff1a;《现代食品》级别&#xff1f; 答&#xff1a;省级。主管单位&#xff1a; 中粮工程科技有限公司 主办单位…

韩国汽车工业的绿色革命:古瑞瓦特光伏逆变器助力能源转型与可持续发展

韩国汽车工业的绿色革命&#xff1a;古瑞瓦特光伏逆变器助力能源转型与可持续发展 汉江奇迹 带来韩国的工业化和现代化 能源的可持续供给 逐步成为韩国工业发展的关键议题为此&#xff0c;韩国颁布了「国家能源基本计划」 推动再生能源发展 预计到2030年新能源电力占总电力的20…

CCS10导入CCS3.3工程

选择工程 下一步 下一步 下一步 下一步 去掉XDAIS 下一步 下一步编译

QT 对话框 仿文本编辑器

对话框通常是一个顶层窗口&#xff0c;出现在程序最上层&#xff0c;用于实现短期任务或者简洁的用户交互 一、消息对话框&#xff08;QMessageBox&#xff09; 1、QMessageBox类成员函数实现 1&#xff09;实例化 QMessageBox类 对象 2&#xff09;设置对象属性 3&#x…