为何JWT采用Base64url编码而非Percent-encoding(即URL编码)
为什么JWT选择Base64url而非Percent-Encoding?
核心原因是两种编码的设计目标、效率和适用场景完全不同,JWT选Base64url是为了满足令牌在多场景传递的紧凑性、安全性和易用性,并非你对两种编码的用途有误解。
1. 编码效率与紧凑性差异
- Base64url是二进制转文本的编码,每3字节原始数据编码为4个字符,能最大化压缩文本长度;而Percent-Encoding是字符转义机制,每个非URL安全字符(包括很多JSON里的常规字符)会被转成3个字符(比如
{会变成%7B)。 - JWT的Header和Payload是JSON结构,字符量不小,用Base64url能大幅缩短令牌长度——这对URL参数、HTTP Header(比如Authorization头)这类有长度限制的场景至关重要,避免因令牌过长导致传输失败或性能损耗。
2. URL友好性的本质区别
- Percent-Encoding的作用是转义个别特殊字符,让任意文本能塞进URL,但转义后的字符串会充满
%符号,可读性差,且容易出现重复转义的问题(比如某些框架会自动对URL参数再次转义,导致解析错误)。 - Base64url的字符集(
A-Za-z0-9_-)完全属于URL安全字符,不需要额外转义就能直接在URL、HTTP Header、Cookie等场景中使用,作为一个完整的令牌,它是单一、干净的标识符,不会被解析器拆分或误处理。
3. 语义与用途定位不同
- Percent-Encoding是字符适配工具,解决的是“如何把任意字符放进URL的有限字符集”的问题;而Base64url是二进制序列化工具,JWT的Header和Payload本质是UTF-8编码的二进制数据,Base64url将其转换成可跨系统传递的文本格式,适用于令牌这种需要可靠传输的凭证。
4. 生态支持并不逊色
- 虽然Percent-Encoding原生支持广泛,但主流编程语言对Base64url的实现也非常成熟:
- PHP:可以用
base64_encode()后替换+为-、/为_,并去除末尾的=填充符 - JavaScript:通过
btoa()生成标准Base64后替换字符,现代环境也可结合TextEncoder实现更规范的编码 - .NET:用
Convert.ToBase64String()后替换字符,或者使用专门的JWT库内置方法
- PHP:可以用
- 几乎所有JWT第三方库都已经封装了Base64url的处理逻辑,开发者不需要手动实现复杂的编码步骤。
关于URL传输场景的补充
正因为JWT常通过URL传输,Base64url的优势才更明显:它能让令牌保持简洁、无特殊字符的格式,不会触发URL解析器的转义逻辑,也不会因长度超标导致问题。如果用Percent-Encoding处理整个JWT,令牌长度会大幅增加,还可能在前后端传递过程中出现转义不一致的问题,导致令牌解析失败。
内容的提问来源于stack exchange,提问作者Advena
相关产品推荐
相关产品推荐

