前端请求加签后后端验签失败是怎么回事?

宇文岳阳 阅读 3

我在前端用用户密钥对请求参数做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 收藏
二维码
手机扫码查看
1 条解答
シ永景
シ永景 Lv1
我看你这个问题,加签验签确实容易出错。让我一步步帮你分析下可能的原因。

首先你要确认后端用的加签方式和前端完全一致。我怀疑问题可能出在几个细节上:

1. 时间戳格式:前端用的是毫秒级时间戳,后端可能是秒级。建议改成整数除以1000取整后再传。像这样:
params.timestamp = Math.floor(Date.now() / 1000);


2. 参数编码:请求参数在传输过程中可能会被URL编码,导致签名不匹配。加签前最好先对参数值做一次encodeURIComponent:
const queryStr = sortedKeys.map(k => ${k}=${encodeURIComponent(params[k])}).join('&');


3. 拼接顺序:有时需要在最后加上一个固定字符串或换行符,具体要看后端实现。原理是这样,两边必须一模一样。

4. 最重要的,secretKey要完全一致且不能有空格。建议打印出来debug一下看看是不是多了空格或者大小写不对。

再来个完整示例代码:

const params = { a: 1, b: 'test' };
params.timestamp = Math.floor(Date.now() / 1000); // 统一时间戳格式
params.nonce = 'abc123';

const sortedKeys = Object.keys(params).sort();
// 对参数值进行url编码
const queryStr = sortedKeys.map(k => ${k}=${encodeURIComponent(params[k])}).join('&');

// 确保密钥正确
const signature = CryptoJS.HmacSHA256(queryStr, secretKey.trim()).toString();


要是还不行,就把前后端的sign过程都打出来对比一下,肯定能找到差异点。这活儿确实挺折磨人的,不过耐心找总能解决。
点赞
2026-03-30 09:03