Postman调用澳大利亚维州PTV时刻表API签名参数问题求助
问题:PTV时刻表API签名验证失败(403错误)
我正尝试用Postman调用维多利亚州PTV(Public Transport Victoria)的时刻表API,已通过邮件拿到有效的developer id(devid)和API密钥。按照官方文档要求,需要计算**包含devid的请求路径(不含基础URL)**与API密钥的HMAC-SHA1哈希值,作为signature查询参数加入请求,但发送请求后一直返回403错误:
{ "message": "Forbidden (403): Supplied signature is invalid for request.", "status": { "version": "3.0", "health": 1 } }
已确认:
- devid有效(用错误devid会返回不同提示)
- 服务器能接收到
signature参数(省略时返回400错误)
当前使用的预请求脚本:
const apiKey = 'obfiscat-edBu-tDas-hesI-nRightPosies'; // 实际为十六进制字符(0-9abcdef) const devid = '1234567'; // 实际为同位数十进制数字 let path = pm.request.url.getPath(); const pathAndQueryString=`${path}?devid=${devid}`; console.log(pathAndQueryString); var sha1Hash = CryptoJS.SHA1(pathAndQueryString,apiKey).toString(); console.log(`Hash of '${pathAndQueryString}' is '${sha1Hash}'`); // 将哈希值保存到Postman的signature变量 pm.variables.set('signature',sha1Hash.toString());
请求端点配置:
{{baseUrl}}/v3/route_types?devid={{devid}}&signature={{signature}}
其中集合变量baseUrl设为https://timetableapi.ptv.vic.gov.au
解决方案
核心问题分析
- CryptoJS API使用错误:你用了
CryptoJS.SHA1(),这是普通SHA1哈希,而非PTV要求的HMAC-SHA1签名,需要改用CryptoJS.HmacSHA1()方法。 - API密钥未正确解析:PTV的API密钥是十六进制字符串,需要先移除连字符并转换为字节数组——CryptoJS默认把字符串当作UTF-8编码处理,直接传入带连字符的十六进制密钥会导致签名计算错误。
修正后的预请求脚本
const apiKeyHex = 'obfiscat-edBu-tDas-hesI-nRightPosies'; // 实际十六进制密钥 const devid = '1234567'; // 实际devid // 移除密钥中的连字符,转换为CryptoJS可识别的字节数组 const apiKeyBytes = CryptoJS.enc.Hex.parse(apiKeyHex.replace(/-/g, '')); // 获取请求路径(不含基础URL) let path = pm.request.url.getPath(); // 构造待签名的字符串:路径 + ?devid=xxx const signatureString = `${path}?devid=${devid}`; console.log('待签名字符串:', signatureString); // 计算HMAC-SHA1签名,转为十六进制字符串 const hmacSignature = CryptoJS.HmacSHA1(signatureString, apiKeyBytes).toString(CryptoJS.enc.Hex); console.log('计算得到的签名:', hmacSignature); // 保存到Postman变量 pm.variables.set('signature', hmacSignature);
验证步骤
- 替换脚本中的
apiKeyHex和devid为你的实际值 - 发送请求前查看Postman控制台,确认待签名字符串格式正确(比如
/v3/route_types?devid=1234567) - 重新发送请求,验证是否返回正确数据
内容的提问来源于stack exchange,提问作者NULL pointer
相关产品推荐
相关产品推荐

