用加密方式处理传递数据时的字符限制
事情的由来
- 临时被安排开发一个表单页面,扫码进入携带部分固定数据,填入文本和附件后提交。需求非常简单,本来没有当回事,简单,有写好的H5的组件,改改样式分分钟搞定。(* ̄︶ ̄)
- 后来说要在IOS和安卓有同样的上传交互,这个有点麻烦了,因为在企业微信环境,H5无法做到统一,后来决定做成小程序。这个决定成为了问题的导火索。o(╥﹏╥)o
公司小程序扫码跳转逻辑
如下图所示,扫码通过URL进入一个鉴权的H5,再进入目标小程序。
因为上述的逻辑,目标小程序的地址和要携带的参数都通过字段写入二维码URL中,如:
问题出在 {key}={value} 上,因为需要传给小程序的数据有中文,而在跳转H5中,需要生成签名注册,签名又不允许有中文,并且经测试除了中文之外还不允许出现“%”、“+”、“/”(具体请看:JS-SDK使用权限签名算法),这下麻烦了,需要传入的中文,无法直接传递到小程序。
思考解决方式
方向
数据必须带进去,中文无法传递,但是可以传递英文和数字,那把中文变成英文和数字就好啦。 接下来就是找到合适的方式,进行对称加密,将中文加密转码传递,传过去之后在应用中解密。
思路
-
先选择base64加密,但是发现加密的密文中会有“+”、“/”等小程序签名不允许的字符
-
再选择base32加密,损失了一部分体积,但是确保不会再出现特殊字符了
遇到的小麻烦
使用base32.js来做加密解密(base32.js),但是发现加密中文转码出来会是乱码。
const message = 'hello 李雷,I am Jack!';
const encodedMessage = base32.encode(message);
// d1jprv3f4undefined75undefinedxtc94g62v9099gp6ut1
const decodedMessage = base32.encode(message);
// hello&ª×<5sN]U®xjæ÷,I am Jack!
太懒了,不想换包了,就它了,我把中文 encodeURI 转码,再 base32 解密。得到密文后照样画葫芦对称解密,搞定。如下:
const message = 'hello 李雷,I am Jack!';
const encodedMessage = base32.encode(encodeURI(message));
// d1jprv3f4mt309a56rjkjh15712ny9a574jkjgh588vjrj9568r62v9568r4mrb3dcgg
const decodedMessage = decodeURI(base32.encode(message));
// hello 李雷,I am Jack!
附加业务工具
因业务需求,方便业务方使用,开发了一个生成加密密文的工具,
- 在工具中使用 base32.encode(encodeURI(原文)) 加密
- 在小程序使用 decodeURL(base32.decode(密文)) 解密
总结
问题的产生总是莫名其秒,难以预测,但是不怕,总有解决的办法,毕竟,程序员是熟练工种,写着写着就熟了!
转载自:https://juejin.cn/post/7269344535368548371