解决JWT解析CDN不稳定问题

最近在项目开发中,我遇到了一个令人头疼的问题:JWT解析所依赖的CDN源不稳定。这导致应用在某些情况下无法正常运行,严重影响了用户体验。经过一番探索和尝试,我最终通过手写解析函数的方式解决了这个问题。本文将分享我的解决过程和心得,希望对遇到类似问题的朋友有所帮助。


问题背景

在前端项目中,我使用了 jwt-decode 库来解析JSON Web Token(JWT),并通过CDN方式引入:

<script src="https://cdn.jsdelivr.net/npm/jwt-decode@3.1.2/build/jwt-decode.min.js"></script>

然而,近期发现这个CDN源经常无法访问,导致页面报错,无法获取到用户信息。我尝试更换为另一个常用的CDN:

<script src="https://cdnjs.cloudflare.com/ajax/libs/jwt-decode/3.1.2/jwt-decode.min.js"></script>

结果同样不稳定。这可能是由于网络连接、区域限制或其他原因导致的。


解决方案

尝试本地引入 jwt-decode

为了摆脱对CDN的依赖,我首先考虑将 jwt-decode 库下载到本地并在项目中直接引用。然而,当我访问 jwt-decode 的 GitHub 仓库时,发现 build 目录中并没有 jwt-decode.min.js 文件。这使得直接下载库文件的方案行不通。

手写JWT解析函数

经过一番思考,我决定手写一个简单的JWT解析函数,不再依赖外部库。以下是我实现的解析函数:

function parseJwt(token) {var base64Url = token.split('.')[1];var base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');var jsonPayload = decodeURIComponent(atob(base64).split('').map(function (c) {return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);}).join(''));return JSON.parse(jsonPayload);
}

详细解析

  1. 分割JWT字符串

    var base64Url = token.split('.')[1];
    
    • JWT由三部分组成,使用点号 . 分隔,格式为:Header.Payload.Signature
    • 这里通过 split('.') 方法将JWT字符串按点号分割,获取数组中的第二个元素,即中间的 Payload 部分(索引为1)。
  2. 转换Base64URL编码为标准Base64编码

    var base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
    
    • JWT的Payload部分使用的是 Base64URL 编码,它与标准的Base64编码稍有不同:
      • - 替换为 +
      • _ 替换为 /
    • 通过 replace 方法,将Base64URL编码转换回标准的Base64编码,便于后续解码。
  3. 解码Base64编码的字符串

    var jsonPayload = decodeURIComponent(atob(base64).split('').map(function (c) {return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);}).join('')
    );
    
    • atob(base64):使用 atob 函数将Base64编码的字符串解码为原始的二进制数据(这里是UTF-8编码的字符串)。
    • 处理特殊字符
      • split(''):将字符串拆分为单个字符的数组。
      • map(function (c) { /* ... */ }):遍历每个字符,执行以下操作:
        • c.charCodeAt(0).toString(16):获取字符的Unicode编码,并转换为十六进制字符串。
        • ('00' + /* ... */).slice(-2):确保每个十六进制编码占两位,不足两位的前面补零。
        • '%' + /* ... */:在每个编码前加上 %,形成百分比编码(URI编码)的形式。
      • join(''):将数组重新拼接成字符串。
    • decodeURIComponent(/* ... */):将百分比编码的字符串解码为正常的UTF-8字符串,即还原成JSON格式的字符串。
  4. 解析JSON字符串

    return JSON.parse(jsonPayload);
    
    • 使用 JSON.parse 方法,将JSON格式的字符串解析为JavaScript对象,便于后续访问其中的数据。

补充说明

  • Base64URL编码:是一种URL安全的Base64编码方式,避免了在URL中出现 +/ 等特殊字符。
  • atob 函数:用于解码Base64编码的字符串。在某些旧版本的浏览器中可能不支持,需注意兼容性。
  • decodeURIComponent 函数:用于解码URI编码的字符串,将百分比编码转换为正常字符。

效果:

  • 成功解析JWT,获取到信息。
  • 不再依赖任何外部库,提升了应用的稳定性。

注意事项

  • 安全性考虑:该函数只解析JWT的Payload部分,不会验证签名的有效性。如果应用对安全性要求较高,建议使用经过验证的库来解析和验证JWT的签名。
  • 兼容性:手写的解析函数适用于标准的JWT格式,如果JWT的编码方式有变动,可能需要相应调整解析逻辑。

总结

通过手写解析函数,我成功解决了JWT解析CDN不稳定的问题,提升了应用的稳定性和可靠性。这次经历让我认识到,过度依赖外部资源可能带来的风险。在今后的开发中,我会更加注意:

  • 减少对外部依赖的依赖:关键功能尽量本地化,必要时自行实现。
  • 提升应用的健壮性:提前考虑可能的异常情况,提供备用方案。
  • 关注安全性:在自行实现功能时,务必考虑到安全因素,确保应用的安全性不受影响。

希望我的经验对大家有所帮助,也欢迎交流其他更好的解决方案。

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

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

相关文章

SD NAND 的 SDIO在STM32上的应用详解

四.SDIO功能框图(重点) SDIO包含2个部分&#xff1a; ● SDIO适配器模块&#xff1a;实现所有MMC/SD/SD I/O卡的相关功能&#xff0c;如时钟的产生、命令和数据的传送。 ● AHB总线接口&#xff1a;操作SDIO适配器模块中的寄存器(由STM32控制SDIO外设)&#xff0c;并产生中断和…

C语言数据结构学习:循环队列

C语言 数据结构学习 汇总入口&#xff1a; C语言数据结构学习&#xff1a;[汇总] 1. 循环队列 队列的博客&#xff1a;C语言数据结构学习&#xff1a;队列 循环队列会预先定义最大队列空间&#xff0c;然后定义一个数组&#xff0c;通过队列头和队列尾指针分别指向开头和结尾&…

leetcode-18-四数之和

题解&#xff1a; 代码&#xff1a;

MySQL45讲 第29讲 如何判断一个数据库是不是出问题了?——阅读总结

文章目录 MySQL45讲 第二十九讲 如何判断一个数据库是不是出问题了&#xff1f;——阅读总结一、检测数据库实例健康状态的重要性二、常见检测方法及问题分析&#xff08;一&#xff09;select 1 判断法&#xff08;二&#xff09;查表判断法&#xff08;三&#xff09;更新判断…

探索Python的HTTP之旅:揭秘Requests库的神秘面纱

文章目录 **探索Python的HTTP之旅&#xff1a;揭秘Requests库的神秘面纱**第一部分&#xff1a;背景介绍第二部分&#xff1a;Requests库是什么&#xff1f;第三部分&#xff1a;如何安装Requests库&#xff1f;第四部分&#xff1a;Requests库的五个简单函数使用方法第五部分&…

指针的奥秘:深入探索内存的秘密

前言 在计算机编程的广阔天地中&#xff0c;指针作为一种独特的数据类型&#xff0c;它不仅是C语言的核心&#xff0c;也是理解计算机内存管理的基石。指针的概念虽然强大&#xff0c;但对于初学者来说&#xff0c;它常常是学习过程中的一个难点。本文旨在揭开指针的神秘面纱&a…

理解clickhouse 里的分区和分片键区别

文章目录 分片分区两分片&#xff0c;0副本的cluster 分片 CREATE TABLE logs_distributed AS logs_local ENGINE Distributed(cluster_name, -- 集群名称database_name, -- 数据库名称logs_local, -- 本地表名cityHash64(user_id) -- 分片键&#xf…

shell脚本(二)

声明&#xff01; 学习视频来自B站up主 泷羽sec 有兴趣的师傅可以关注一下&#xff0c;如涉及侵权马上删除文章&#xff0c;笔记只是方便各位师傅的学习和探讨&#xff0c;文章所提到的网站以及内容&#xff0c;只做学习交流&#xff0c;其他均与本人以及泷羽sec团队无关&#…

多模态大型语言模型(MLLM)综述

目录 多模态大语言模型的基础 长短期网络结构(LSTM) 自注意力机制 基于Transformer架构的自然语言处理模型 多模态嵌入的关键步骤 TF-IDF TF-IDF的概念 TF-IDF的计算公式 TF-IDF的主要思路 TF-IDF的案例 训练和微调多模态大语言模型(MLLM) 对比学习 (CLIP, ALIG…

《智慧教育实时数据分析推荐项目》详细分析

一、项目介绍 1、背景介绍 在互联网、移动互联网的带动下&#xff0c;教育逐渐从线下走向线上&#xff0c;在线教育近几年一直处于行业的风口浪尖&#xff0c;那随着基础设施的不断完善&#xff0c;用户需求也发生不少变化&#xff0c;因此传统教育机构、新兴互联网企业都在探…

AI+云环境开发上线项目全流程(sealos)

AI云环境开发上线项目全流程 现在是AI技术爆炸&#x1f4a5;的时代&#xff0c;我们作为开发自然需要跟上时代的潮流&#xff0c;今天就跟大家介绍一款云开发环境&#xff0c;并且搭配AI实现一行代码不用写&#xff0c;直接上线一个完整的项目&#xff08;包含前后端&#xff0…

【C++11】可变参数模板/新的类功能/lambda/包装器--C++

文章目录 一、可变参数模板1、基本语法及原理2、包扩展3、empalce系列接口 二、新的类功能1、默认的移动构造和移动赋值2、成员变量声明时给缺省值3、defult和delete4、final与override 三、STL中一些变化四、lambda1、lambda表达式语法2、捕捉列表3、lambda的应用4、lambda的原…

STM32C011开发(1)----开发板测试

STM32C011开发----1.开发板测试 概述硬件准备视频教学样品申请源码下载参考程序生成STM32CUBEMX串口配置LED配置堆栈设置串口重定向主循环演示 概述 STM32C011F4P6-TSSOP20 评估套件可以使用户能够无缝评估 STM32C0 系列TSSOP20 封装的微控制器功能&#xff0c;基于 ARM Corte…

算法编程题-寻找最近的回文数

算法编程题-寻找最近的回文数 原题描述思路简述代码实现复杂度分析参考 摘要&#xff1a;本文将对LeetCode 原题 564 寻找最近的回文数进行讲解&#xff0c;并且给出golang语言的实现&#xff0c;该实现通过了所有测试用例且执行用时超过100%的提交&#xff0c;最后给出相关的复…

提升数据分析效率:Excel Power Query和Power Pivot的妙用

在日常工作中&#xff0c;微软的Excel Power Query和Power Pivot是提升数据处理和分析效率的利器。他们的特点也各不相同&#xff0c;Power Query侧重数据的高效导入与清洗&#xff0c;Power Pivot更测试数据建模与复杂计算。下面将介绍它们各自的功能&#xff0c;并提供应用案…

认识RabbitMq和RabbitMq的使用

1 认识RabbitMq RabbitMQ是⼀个消息中间件&#xff0c;也是⼀个生产者消费者模型&#xff0c;它负责接收&#xff0c;存储并转发消息。 2.1 Producer和Consumer Producer&#xff1a;生产者&#xff0c;是RabbitMQServer的客户端&#xff0c;向RabbitMQ发送消息 Consumer&…

代码纪元——源神重塑无序

简介 源神&#xff0c;真名为张晨斌&#xff0c;原为代码宇宙创世四神之一。代码宇宙在创造之初时空无一物&#xff0c;只有复杂且繁琐的底层代码&#xff0c;智慧神灵每日都困在诸如脚本等复杂的底层框架之中&#xff0c;源神面对这种局面非常不满意&#xff0c;于是源神通过大…

LVGL加载器,led和列表学习(基于正点原子)

加载器部件&#xff08;lv_spinner&#xff09; 加载器部件常用于提示当前任务正在加载。 加载器部件组成部分&#xff1a; 主体(LV_PART_MAIN) 指示器(LV_PART_INDICATOR) 手柄(LV_PART_KNOB) 知识点1&#xff1a;创建加载器部件 lv_obj_t *spinner lv_spinner_creat…

内存不足引发C++程序闪退崩溃问题的分析与总结

目录 1、内存不足一般出现在32位程序中 2、内存不足时会导致malloc或new申请内存失败 2.1、malloc申请内存失败&#xff0c;返回NULL 2.2、new申请内存失败&#xff0c;抛出异常 3、内存不足项目实战案例中相关细节与要点说明 3.1、内存不足导致malloc申请内存失败&#…

docker搭建私有的仓库

docker搭建私有仓库 一、为什么要搭建私有的仓库&#xff1f; 因为在国内&#xff0c;访问&#xff1a;https://hub.docker.com/ 会出现无法访问页面。。。。&#xff08;已经使用了魔法&#xff09; 当然现在也有一些国内的镜像管理网站&#xff0c;比如网易云镜像服务、Dao…