You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从对象存储获取Base64格式JWT后解码失败,请求DataWeave错误排查

解决DataWeave解码JWT时的"Illegal base64 character 2e"错误

这个报错的根源很明确:你直接把整个JWT令牌传给fromBase64()函数,但JWT本身不是纯Base64字符串——它是由三个Base64URL编码的片段(头部、载荷、签名)用点(.)拼接而成的,而点字符(ASCII码2e)不在标准Base64的字符集里,所以函数会抛出非法字符的错误。

要正确解码JWT,你需要先拆分令牌,再对每个片段做Base64URL解码(注意Base64URL和标准Base64的细微区别),最后把头部和载荷转换成JSON结构。下面是一步步的解决方案:

步骤1:理解JWT的结构

你的JWT令牌是:
eyJhbGciOiJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzA0L3htbGRzaWctbW9yZSNobWFjLXNoYTI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VySUQiOiIxNzMzIiwiVXNlck5hbWUiOiJhY2hhbjAzMiIsIkN1bHR1cmVUYWciOm51bGwsImlhdCI6IjE1Njc2Njk3MDgiLCJleHAiOiIxNTY3NzU2MTA4IiwiaXNzIjoiVGltZVNoYXJlV2FyZSIsImF1ZCI6Imh0dHBzOi8vVGltZVNoYXJlV2FyZS5jb20vIn0.w2h6j7gbAs6CouE9WoYEDQRzBYEsNIqry70w2K4JAZg

用.拆分后得到三个部分:

  • 头部:eyJhbGciOiJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzA0L3htbGRzaWctbW9yZSNobWFjLXNoYTI1NiIsInR5cCI6IkpXVCJ9
  • 载荷:eyJVc2VySUQiOiIxNzMzIiwiVXNlck5hbWUiOiJhY2hhbjAzMiIsIkN1bHR1cmVUYWciOm51bGwsImlhdCI6IjE1Njc2Njk3MDgiLCJleHAiOiIxNTY3NzU2MTA4IiwiaXNzIjoiVGltZVNoYXJlV2FyZSIsImF1ZCI6Imh0dHBzOi8vVGltZVNoYXJlV2FyZS5jb20vIn0
  • 签名:w2h6j7gbAs6CouE9WoYEDQRzBYEsNIqry70w2K4JAZg

步骤2:编写DataWeave脚本解码

下面的脚本会自动拆分JWT,处理Base64URL到标准Base64的转换,然后解码并转成JSON:

%dw 2.0
import * from dw::core::Binaries
import * from dw::core::Strings
output application/json

// 自定义函数:处理Base64URL解码(替换特殊字符+补填充)
fun base64UrlDecode(str: String): String = 
    fromBase64(
        // 将Base64URL的"-"和"_"替换为标准Base64的"+"和"/"
        (str replace "-" with "+" replace "_" with "/") 
        // 补充Base64需要的"="填充字符
        ++ (if ((str length mod 4) > 0) ("=" * (4 - (str length mod 4))) else "")
    ) as String

// 拆分JWT为三个部分
var jwtSegments = payload as String splitBy "."
---
{
    // 解码头部并转成JSON
    header: base64UrlDecode(jwtSegments[0]) read application/json,
    // 解码载荷并转成JSON
    payload: base64UrlDecode(jwtSegments[1]) read application/json,
    // 解码签名(转成字符串方便查看,也可以保留Binary类型)
    signature: fromBase64(
        (jwtSegments[2] replace "-" with "+" replace "_" with "/") 
        ++ (if ((jwtSegments[2] length mod 4) > 0) ("=" * (4 - (jwtSegments[2] length mod 4))) else "")
    ) as Binary as String
}

运行结果

执行这个脚本后,你会得到符合预期的结构:

{
  "header": {
    "alg": "http://www.w3.org/2001/04/xmldsig-more#hmac-sha256",
    "typ": "JWT"
  },
  "payload": {
    "UserID": "1733",
    "UserName": "achan032",
    "CultureTag": null,
    "iat": "1567669708",
    "exp": "1567756108",
    "iss": "TimeShareWare",
    "aud": "https://TimeShareWare.com/"
  },
  "signature": "w2h6j7gbAs6CouE9WoYEDQRzBYEsNIqry70w2K4JAZg"
}

额外提示

如果你只需要头部和载荷(签名通常用于验证,不需要解析内容),可以去掉签名部分的处理,简化脚本。另外,注意JWT的载荷是明文编码的,不需要密钥就能解码,这是正常的设计——签名才是用来验证内容完整性的。

内容的提问来源于stack exchange,提问作者Rishul Saxena

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:59:42