node中使用jsonwebtoken 解析jwt token时报 invalid token的解决办法

本文记录了解决前端使用JWT生成并验证token时,因未移除空格导致的登录失败问题,分享解决方法和踩坑经验。

出现背景,登录时根据jwt使用生成token,如下图

 

然后登录成功时根据后台返回的token解析jwt令牌,关键部分代码如下

前端点击登录会出现invalid token报错,如下图

就在我百思不得其解百度了各种办法都试了没效果之后,突然发现我没有把token前的空格去掉

解决办法:

此篇仅作为我的踩坑记录

<think>我们需要在TypeScript中解析JWT(JSON Web Token)。JWT由三部分组成:头部(Header)、负载(Payload)和签名(Signature),它们之间用点(.)分隔。解析JWT通常包括以下步骤: 1. 将JWT按点拆分成三个部分。 2. 对头部和负载进行Base64Url解码。 3. 将解码后的头部和负载解析为JSON对象。 注意:我们这里只做解析,不验证签名,因为验证签名需要密钥和算法,并且通常需要依赖库(如jsonwebtoken)。这里我们只关注如何从JWT字符串中提取信息。 步骤: 1. 分割字符串,得到三个部分:header, payload, signature。 2. 对header和payload进行Base64Url解码(Base64Url解码需要将URL安全的Base64转换为标准Base64,即替换字符并处理填充)。 3. 将解码后的字符串解析为JSON对象。 注意:Base64Url与标准Base64的不同之处在于: - 替换'+'为'-' - 替换'/'为'_' - 去掉填充'='(但解码时我们需要补足等号以保证正确解码) 在TypeScript(JavaScript)中,我们可以使用`Buffer`(Node.js环境)或`atob`(浏览器环境)来进行Base64解码。这里我们假设在Node.js环境中使用Buffer。 但是,为了通用性,我们可以写一个函数来处理Base64Url解码。如果是在浏览器环境中,我们可以使用`atob`,但需要先替换字符并补足等号。 由于问题没有指定环境,我将提供一个适用于Node.js环境的解决方案,因为TypeScript通常运行在Node.js环境或浏览器环境。这里我们以Node.js为例。 代码示例: </think>在 TypeScript 中解析 JWT Token 不需要额外依赖第三方库,可通过原生 JavaScript 实现。以下是详细实现和解析逻辑: ```typescript /** * 解析 JWT Token 的函数 * @param token JWT 字符串 * @returns 解析后的 payload 对象 */ function parseJwt(token: string): Record<string, any> | null { try { // 1. 分割 Token 的三部分 const parts = token.split('.'); if (parts.length !== 3) { throw new Error('Invalid JWT format'); } // 2. 提取 Base64Url 编码的 payload const payloadBase64Url = parts[1]; // 3. Base64Url 转标准 Base64 const payloadBase64 = payloadBase64Url .replace(/-/g, '+') .replace(/_/g, '/'); // 4. 补全 Base64 末尾的等号 const paddedPayloadBase64 = payloadBase64.padEnd( payloadBase64.length + (4 - (payloadBase64.length % 4)) % 4, '=' ); // 5. 解码并解析 JSON const jsonPayload = decodeURIComponent( atob(paddedPayloadBase64) .split('') .map(c => '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2)) .join('') ); return JSON.parse(jsonPayload); } catch (error) { console.error('JWT 解析失败:', error); return null; } } // 使用示例 const jwtToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c'; const payload = parseJwt(jwtToken); console.log('解析结果:', payload); /* 输出: { "sub": "1234567890", "name": "John Doe", "iat": 1516239022 } */ ``` ### 关键步骤解释: 1. **分割 JWT 结构** JWT 格式为 `header.payload.signature`,使用 `.` 分割后取第二部分(索引1)的 payload 2. **Base64Url 解码** JWT 使用 URL 安全的 Base64 编码(Base64Url),需进行转换: - 将 `-` 替换为 `+` - 将 `_` 替换为 `/` - 补全末尾的 `=` 填充符(Base64 要求长度是4的倍数) 3. **解码 UTF-8 数据** 使用 `atob()` 解码 Base64 后,通过 URI 组件解码处理特殊字符: - 将每个字符转换为 `%xx` 十六进制格式 - 使用 `decodeURIComponent` 还原原始字符串 4. **JSON 解析** 将解码后的字符串解析为 JavaScript 对象 ### 使用注意事项: 1. **签名验证** 此方法 **仅解析** payload,不验证签名合法性。生产环境中应使用 `jsonwebtoken` 等库进行完整验证: ```bash npm install jsonwebtoken @types/jsonwebtoken ``` ```typescript import jwt from 'jsonwebtoken'; const verified = jwt.verify(token, 'YOUR_SECRET_KEY'); ``` 2. **Token 过期检查** 解析后可检查 `exp` 字段(Expiration Time)判断是否过期: ```typescript if (payload.exp && payload.exp * 1000 < Date.now()) { throw new Error('Token expired'); } ``` 3. **浏览器兼容性** `atob` 在浏览器中可用,Node.js 环境需使用 `Buffer`: ```typescript // Node.js 替代方案 const jsonPayload = Buffer.from(paddedPayloadBase64, 'base64').toString('utf-8'); ```
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值