如何在JavaScript(Node.js)中生成与PHP输出一致的HMAC-SHA256 Token
如何在JavaScript(Node.js)中生成与PHP输出一致的HMAC-SHA256 Token
我帮你搞定这个问题!要让Node.js生成和PHP完全一致的Token,得先把PHP那行代码的逻辑拆透,再对应到Node.js的crypto模块上,一步步来:
先拆透PHP代码的核心逻辑
你用的PHP代码看似一行,其实藏了几个关键细节:
- 时间格式:
gmdate('y-m-d H')取的是格林威治标准时间(GMT),格式是「两位年份-两位月份-两位日期 24小时制小时」,比如24-05-20 15 - 消息构造:把你的邮箱和上面的时间串用冒号拼接,比如
user@example.com:24-05-20 15 - HMAC计算:用SHA256算法,密钥是你的API Key,重点:PHP的
hash_hmac默认返回的是十六进制(hex)字符串,不是原始二进制数据 - 最终编码:把这个十六进制字符串再做Base64编码,才得到最终的Token
Node.js的正确实现代码
你之前写的代码应该是卡在时间格式和HMAC输出格式上了,直接给你能跑的正确版本:
import crypto from "crypto"; function generateToken(apiKey, email) { // 生成和PHP gmdate('y-m-d H')完全一致的GMT时间串 const now = new Date(); // 取年份后两位(四位数年份转成两位) const year = String(now.getUTCFullYear()).slice(-2); // 月份从0开始,要+1后补零(比如5月→05) const month = String(now.getUTCMonth() + 1).padStart(2, '0'); // 日期和小时都要补零(比如8号→08,9点→09) const day = String(now.getUTCDate()).padStart(2, '0'); const hour = String(now.getUTCHours()).padStart(2, '0'); const timestamp = `${year}-${month}-${day} ${hour}`; // 拼接邮箱和时间串,构造HMAC的消息体 const message = `${email}:${timestamp}`; // 计算HMAC-SHA256,指定输出为十六进制字符串(和PHP默认行为匹配) const hmacHex = crypto.createHmac('sha256', apiKey) .update(message) .digest('hex'); // 把十六进制字符串转成Base64,得到最终Token return Buffer.from(hmacHex).toString('base64'); } // 测试:替换成你的实际API Key和邮箱 console.log(generateToken('your-api-key', 'user@example.com'));
必须注意的坑(不然肯定不一致)
- 绝对不能用本地时间!一定要用
getUTC*系列方法获取GMT时间,PHP的gmdate是GMT,用本地时间的话,只要时区不一样,时间串就对不上 - 数字补零不能忘:PHP的
gmdate会自动把单个数字的月、日、小时补成两位,Node.js得手动用padStart(2, '0')处理,不然比如5月写成5而不是05,消息体就错了 - HMAC的输出格式要对应:PHP默认返回hex字符串,Node.js里必须指定
digest('hex'),要是直接用默认的buffer或者base64,结果肯定和PHP不一样
备注:内容来源于stack exchange,提问作者Sumudu madushan
相关产品推荐
相关产品推荐

