后端生成的URL中含base64参数值,经tomcat重定向后偶发前端无法解密报错

现象

最近定位到一个有意思的bug,后端生成的URL中包含base64参数值后,经过tomcat重定向后,偶发出现前端无法解密的现象。

原因

当出现问题时,经排查发现重定向的Location响应头中把+转成了 英文空格,导致解密失败。

重定向时如果特殊字符未经URLEncode转义,则tomcat会把+转换成英文空格。

处理方案

方案1、对Base64参数值进行UrlEncode。推荐

此方案会将所有特殊符号替换成%数字字母格式,如%2B,最后一个字母大小写不敏感。

Java代码:

java 复制代码
String plainText = "hello>";
String encodedText = Base64.getEncoder().encodeToString(plainText.getBytes(StandardCharsets.UTF_8));
String urlEncodedText = URLEncoder.encode(url, StandardCharsets.UTF_8.toString());

response.sendRedirect("http://127.0.0.1:8080/test?encode=" + urlEncodedText); //http://127.0.0.1:8080/test?encode=aGVsbG8%2B

JavaScript代码:

js 复制代码
const encode = 'aGVsbG8%2B'
const decode = atob(decodeURIComponent(encode))
console.log(decode) //hello>

方案2、Base64使用UrlEncoder进行加密。需前端配合

基于2006年的RFC规范:RFC4648 URL安全字符串替换(+替换成-/替换成_),需要前端配合

Java代码:

java 复制代码
String plainText = "hello>";
String encodedText = Base64.getUrlEncoder().encodeToString(plainText.getBytes(StandardCharsets.UTF_8));

response.sendRedirect("http://127.0.0.1:8080/test?encode=" + encodedText); //http://127.0.0.1:8080/test?encode=aGVsbG8-

JavaScript代码:

js 复制代码
//写法1:替换回-为+,_为/,补全=,使用atob()完成base64解密
const encodeText = 'aGVsbG8-'
let encode = encodeText.replace(/-/g, '+')
                       .replace(/_/g, '/')
                       .padEnd(encodeText.length + (4 - encodeText.length % 4) % 4, '=');

const result = atob(decodeURIComponent(encode))
console.log(result)


//写法2:使用TextDecoder解密
<script src="https://unpkg.com/base64-js/base64js.min.js"></script>
<script>
function decodeBase64Url(base64UrlString) {
    // 需补全结尾=号,TextDecoder内部处理过替换
    const base64 = base64UrlString
        .padEnd(base64UrlString.length + (4 - base64UrlString.length % 4) % 4, '=');
    
    // 解码支持
    const byteArray = base64js.toByteArray(base64);
    return new TextDecoder().decode(byteArray);
}
console.log(decodeBase64Url('aGVsbG8-'))
</script>

方案3、调整tomcat配置

不推荐,可自行搜索。

相关推荐
xcl09254 小时前
商超智能运营实战:数据驱动提升门店效率与体验指南
java·mfc·宠物
web打印社区5 小时前
网页静默打印热敏小票:从 HTML 到出纸的完整指南
前端·javascript·vue.js·electron·pdf·html
剪刀石头布啊6 小时前
设计一个多计时任务的任务管理功能
前端
Flynt6 小时前
OpenJDK禁AI代码半年了,现在执行得怎么样?答案是:全靠自觉
java·开源·ai编程
ModyQyW7 小时前
vite-plugin-uni-manifest 更新了什么
前端·typescript·uni-app
Asize8 小时前
AI 协作开发新范式:我用 SDD 做了个排版 npm 包
前端·人工智能
kyriewen9 小时前
我把今年流传的前端 AI 面试题整理了一遍——4 类场景题+回答框架(附速查表)
前端·面试·程序员
计算机魔术师10 小时前
国产多模态模型正面硬刚Opus旗舰:差距从30%缩到3%
前端
风骏时光牛马10 小时前
程序员进阶:深度思考,解锁职场成长的底层逻辑
前端
IT_陈寒10 小时前
用了Proxy才发现以前的JavaScript白写了
前端·人工智能·后端