JWT 由三个部分组成,用点分隔: header.payload.signature
我有以下有效负载,我正在尝试使用
base64 -d
命令在终端中对其进行解码:
payload=eyJ0b2tlbl90eXBlIjoicmVmcmVzaCIsImV4cCI6MTY3OTMxMzgyMSwiaWF0IjoxNjc5MTQxMDIxLCJqdGkiOiIzZjM4ZTVmZTBmNGE0N2E0ODg2MGM4M2FmYmNhNTAzZiIsInVzZXJfaWQiOjEwfQ
当尝试使用
echo $payload | base64 -d
解码有效负载时,我得到以下输出:
{"token_type":"refresh","exp":1679313821,"iat":1679141021,"jti":"3f38e5fe0f4a47a48860c83afbca503%
输出不包含整个json,它被截断了。
在 Chrome javascript 控制台中使用
atob(payload)
时,这是输出:
{"token_type":"refresh","exp":1679313821,"iat":1679141021,"jti":"3f38e5fe0f4a47a48860c83afbca503f","user_id":10}
这是我期望从解码有效负载中得到的正确的 json 输出!
我有以下问题:
base64 -d
或类似命令解码终端中的有效负载?提前致谢!
附加信息
which base64
返回/usr/bin/base64
您的
$payload
值具有 Base64 编码,但缺少最终填充。来自维基百科:Base64:
由于 Base64 是六位编码,并且解码后的值被分为 8 位八位字节,因此 Base64 编码文本的每四个字符(4 个六位字节 = 4 × 6 = 24 位)代表三个八位字节的未编码文本或数据(3 个八位字节 = 3 × 8 = 24 位)。这意味着,当未编码输入的长度不是三的倍数时,编码输出必须添加填充,使其长度为四的倍数。填充字符是
,这表示不需要更多位来完全编码输入。 […]=
填充字符对于解码来说不是必需的,因为可以从编码文本的长度推断出丢失的字节数。在某些实现中,填充字符是强制性的,而对于其他实现则不使用。
事实证明,JWT 令牌不愿意生成填充字符,而您的
base64
解码器则需要它们的存在。所讨论的实际令牌有 150 个字符,还差两个字符,无法被 4 整除。因此,附加这两个缺失的字符将解决此特定标记的问题,而从变量值的长度推断附加字符的数量将解决一般情况的问题:
echo "$payload==" | base64 -d
# or
echo "$payload$(printf %$(((4-${#payload}%4)%4))s | tr ' ' =)" | base64 -d
{"token_type":"refresh","exp":1679313821,"iat":1679141021,"jti":"3f38e5fe0f4a47a48860c83afbca503f","user_id":10}
或者,使用可以处理不平衡填充的解码器,例如命令行 JSON 处理器jq(您也可以使用它来直接对解码后的令牌进行后处理):
echo "$payload" | jq -R '@base64d | fromjson'
# or
jq -n --arg p "$payload" '$p | @base64d | fromjson'
{
"token_type": "refresh",
"exp": 1679313821,
"iat": 1679141021,
"jti": "3f38e5fe0f4a47a48860c83afbca503f",
"user_id": 10
}