You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 16:25:21