前端请求加签后后端验签失败是怎么回事?
我在前端用用户密钥对请求参数做SHA256加签,但后端老是说签名不匹配,明明参数排序和拼接都按文档来了啊。
试过把时间戳、nonce这些字段都加上,也确认了密钥没传错,可还是不行。是不是我加密的方式有问题?
const params = { a: 1, b: 'test', timestamp: Date.now(), nonce: 'abc123' };
const sortedKeys = Object.keys(params).sort();
const queryStr = sortedKeys.map(k => <code>${k}=${params[k]}</code>).join('&');
const signature = CryptoJS.HmacSHA256(queryStr, secretKey).toString();
首先你要确认后端用的加签方式和前端完全一致。我怀疑问题可能出在几个细节上:
1. 时间戳格式:前端用的是毫秒级时间戳,后端可能是秒级。建议改成整数除以1000取整后再传。像这样:
2. 参数编码:请求参数在传输过程中可能会被URL编码,导致签名不匹配。加签前最好先对参数值做一次encodeURIComponent:
3. 拼接顺序:有时需要在最后加上一个固定字符串或换行符,具体要看后端实现。原理是这样,两边必须一模一样。
4. 最重要的,secretKey要完全一致且不能有空格。建议打印出来debug一下看看是不是多了空格或者大小写不对。
再来个完整示例代码:
要是还不行,就把前后端的sign过程都打出来对比一下,肯定能找到差异点。这活儿确实挺折磨人的,不过耐心找总能解决。