Tuya API调用遭遇1004无效签名错误求助
问题:Tuya API调用返回1004签名无效错误
我是Tuya开发新手,已成功获取access_token且与Postman中的一致,但调用Tuya API时始终返回1004错误,错误信息如下:
{"code":1004,"msg":"sign invalid","success":false,"t":1699465157510,"tid":"bdb815d97e5d11eea3b2361f03176748"}
我查阅了所有官方文档仍未找到问题所在,附上我的PHP代码,且已尝试遵循所有Tuya文档规范:
<?php include "Sdk.php"; date_default_timezone_set('Europe/Malta'); $config = array( "clientID" => "YOUR_CLIENT_ID", "accessUrl" => "https://openapi.tuyaeu.com", "secret" => "YOUR_SECRET_ID", "nonce" => "", ); $request = new SendClient($config); $access_token = $request::$AccessToken; $device_id = "YOUR_DEVICE_ID"; $time = time()*1000; $client_ID = "YOUR_CLIENT_ID"; $secret = "YOUR_SECRET_ID"; $stringToSign = $client_ID . $time; $signature = strtoupper(hash_hmac("sha256", $stringToSign, $secret)); $code = "switch_1"; $value = true; $commands = [ "commands" => [ [ "code" => $code, "value" => $value ] ] ]; $url = "https://openapi.tuyaeu.com/v1.0/devices/{$device_id}/commands"; $headers = [ "access_token: {$access_token}", "Content-Type: application/json", "t: {$time}", "client_id: {$client_ID}", "sign: {$signature}", "sign_method: HMAC-SHA256" ]; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($commands)); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); $output = curl_exec($ch); curl_close($ch); echo $output; ?>
解决方案
1004错误的核心是签名生成不符合Tuya的规范,你当前的签名字符串缺少了access_token和POST请求体两个关键部分,这是导致签名无效的主要原因。根据Tuya开放平台规则,带access_token的接口签名构造逻辑如下:
- 待签名字符串格式:
client_id + access_token + t + nonce + 请求体JSON字符串- 若请求体为空(如GET请求),忽略请求体部分
- nonce可以为空字符串,但必须包含在字符串中
- 使用HMAC-SHA256算法,以你的secret作为密钥,对上述字符串加密后转成大写,得到最终sign值
修正后的代码如下:
<?php include "Sdk.php"; date_default_timezone_set('Europe/Malta'); $config = array( "clientID" => "YOUR_CLIENT_ID", "accessUrl" => "https://openapi.tuyaeu.com", "secret" => "YOUR_SECRET_ID", "nonce" => "", ); $request = new SendClient($config); $access_token = $request::$AccessToken; $device_id = "YOUR_DEVICE_ID"; $time = time()*1000; $client_ID = "YOUR_CLIENT_ID"; $secret = "YOUR_SECRET_ID"; $nonce = $config['nonce']; // 构造请求体JSON $commands = [ "commands" => [ [ "code" => "switch_1", "value" => true ] ] ]; $request_body = json_encode($commands); // 修正签名字符串,加入access_token、nonce和请求体 $stringToSign = $client_ID . $access_token . $time . $nonce . $request_body; $signature = strtoupper(hash_hmac("sha256", $stringToSign, $secret)); $url = "https://openapi.tuyaeu.com/v1.0/devices/{$device_id}/commands"; $headers = [ "access_token: {$access_token}", "Content-Type: application/json", "t: {$time}", "client_id: {$client_ID}", "sign: {$signature}", "sign_method: HMAC-SHA256", "nonce: {$nonce}" // 若nonce不为空,需在请求头中携带 ]; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $request_body); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); $output = curl_exec($ch); curl_close($ch); echo $output; ?>
额外注意事项:
- 确保
time()*1000生成的时间戳(t参数)与服务器时间差不超过5分钟,否则也会导致签名无效 - 请求体的JSON字符串必须和POST发送的内容完全一致,不能有多余空格或格式差异
- 如果使用了nonce参数,需要同时在请求头中携带
nonce字段
内容的提问来源于stack exchange,提问作者Charles Peresso
相关产品推荐
相关产品推荐

