Page 1 of 1
code "1004", msg "sign invalid"
Posted: 2023年 Oct 31日 15:15
by adiot
Hi,
I'm trying to call the API using Postman, but I'm getting a "sign invalid" error
The Postman json file and Enviroments were added by referring to "https://developer.tuya.com/en/docs/iot/ ... o385w1svns"
Below is Postman pre-scripte, where "client_id" and "secret" entered the AccessID and Access Secret without a hitch.
I can't find the cause. Please help me
Code: Select all
(function () {
var timestamp = getTime();
pm.environment.set("timestamp",timestamp);
var clientId = pm.environment.get("client_id");
var secret = pm.environment.get("secret");
var sign = calcSign(clientId,secret,timestamp);
pm.environment.set('easy_sign', sign);
})();
function getTime(){
var timestamp = new Date().getTime();
return timestamp;
}
function calcSign(clientId,secret,timestamp){
var str = clientId + timestamp;
var hash = CryptoJS.HmacSHA256(str, secret);
var hashInBase64 = hash.toString();
var signUp = hashInBase64.toUpperCase();
return signUp;
}
Code: Select all
{
"code": 1004,
"msg": "sign invalid",
"success": false,
"t": 1698735333523,
"tid": "7cb98d1777ba11ee946f2e28f447d5d3"
}
Re: code "1004", msg "sign invalid"
Posted: 2023年 Oct 31日 16:06
by panda-cat
If you encounter this problem, you can check whether the "Current value" set by client_id and secret in the environment configuration file is correct.
Re: code "1004", msg "sign invalid"
Posted: 2023年 Oct 31日 16:24
by panda-cat
I found that your pre-scripte is incomplete. You can re-download a postman collection file and import it into postman. The complete information parameters are as follows:
Code: Select all
(function () {
var timestamp = getTime();
pm.environment.set("timestamp",timestamp);
const clientId = pm.environment.get("client_id");
const secret = pm.environment.get("secret");
var accessToken = "";
if(pm.environment.has("easy_access_token")){
accessToken = pm.environment.get("easy_access_token")
}
const httpMethod = pm.request.method.toUpperCase();
const query = pm.request.url.query;
const mode = pm.request.body.mode;
const headers = pm.request.headers;
// sha256
var signMap = stringToSign(query, mode, httpMethod, secret)
var urlStr = signMap["url"]
var signStr = signMap["signUrl"]
pm.request.url = pm.request.url.host + urlStr
var nonce = ""
if (headers.has("nonce")) {
var jsonHeaders = JSON.parse(JSON.stringify(headers))
jsonHeaders.forEach(function(item){
if (item.key == "nonce" && !item.disabled) {
nonce = headers.get("nonce")
}
})
}
var sign = calcSign(clientId, timestamp, nonce, signStr, secret);
pm.environment.set('easy_sign', sign);
})();
function getTime(){
var timestamp = new Date().getTime();
return timestamp;
}
// Token verification calculation
function calcSign(clientId,timestamp,nonce,signStr,secret){
var str = clientId +timestamp + nonce + signStr;
var hash = CryptoJS.HmacSHA256(str, secret);
var hashInBase64 = hash.toString();
var signUp = hashInBase64.toUpperCase();
return signUp;
}
// // Business verification calculation
// function calcSign(clientId,accessToken,timestamp,nonce,signStr,secret){
// var str = clientId + accessToken +timestamp + nonce + signStr;
// var hash = CryptoJS.HmacSHA256(str, secret);
// var hashInBase64 = hash.toString();
// var signUp = hashInBase64.toUpperCase();
// return signUp;
// }
// Generate signature string
function stringToSign(query, mode, method, secret){
var sha256 = "";
var url = "";
var headersStr = ""
const headers = pm.request.headers;
var map = {}
var arr = []
var bodyStr = ""
if(query){
toJsonObj(query, arr, map)
}
if (pm.request.body && mode) {
if (mode != "formdata" && mode != "urlencoded"){
bodyStr = replacePostmanParams(pm.request.body.toString())
} else if (mode == "formdata") {
// Traversing form key value pairs
toJsonObj(pm.request.body["formdata"], arr, map)
} else if (mode == "urlencoded") {
// Traversing form key value pairs
toJsonObj(pm.request.body["urlencoded"], arr, map)
}
}
sha256 = CryptoJS.SHA256(bodyStr)
arr = arr.sort()
arr.forEach(function(item){
url += item + "=" + map[item] + "&"
})
if (url.length > 0 ) {
url = url.substring(0, url.length-1)
url = "/" + pm.request.url.path.join("/") + "?" + url
} else {
url = "/" + pm.request.url.path.join("/")
}
if (headers.has("Signature-Headers") && headers.get("Signature-Headers")) {
var jsonHeaders = JSON.parse(JSON.stringify(headers))
var signHeaderStr = headers.get("Signature-Headers")
const signHeaderKeys = signHeaderStr.split(":")
signHeaderKeys.forEach(function(item){
var val = ""
if (isSelected(jsonHeaders,item) && headers.get(item)) {
val = headers.get(item)
}
headersStr += item + ":" + val + "\n"
})
}
var map = {}
url = replacePostmanUrl(url)
map["signUrl"] = method + "\n" + sha256 + "\n" + headersStr + "\n" + url
map["url"] = url
return map
}
function isSelected(jsonHeaders,key){
var result = true;
jsonHeaders.forEach(function(item){
if (item.key == key && item.disabled) {
result = false
}
})
return result
}
function replacePostmanParams(str){
while(str.indexOf("{{")!=-1&&str.indexOf("}}")!=-1){
const key = str.substring(str.indexOf("{{")+2,str.indexOf("}}"))
var value = pm.environment.get(key)
if(!value) value=""
str = str.replace("{{"+key+"}}", value)
}
return str
}
function replacePostmanUrl(str){
console.log("str:",str)
while(str.indexOf("{{")!=-1&&str.indexOf("}}")!=-1){
const key = str.substring(str.indexOf("{{")+2,str.indexOf("}}"))
var value = pm.environment.get(key)
if(!value) value=""
str = str.replace("{{"+key+"}}", value)
}
while(str.indexOf(":")!=-1){
const tempStr = str.substring(str.indexOf(":")+1,str.length);
var key = "";
if(tempStr.indexOf("/")!=-1){
key = tempStr.substring(0,tempStr.indexOf("/"))
}else if(tempStr.indexOf("?")!=-1){
key = tempStr.substring(0,tempStr.indexOf("?"))
}else {
key = tempStr.substring(0,tempStr.length)
}
var value = pm.request.url.variables.get(key)
if(!value) value=""
str = str.replace(":"+key, value)
}
return str
}
function toJsonObj(params, arr, map){
var jsonBodyStr = JSON.stringify(params)
var jsonBody = JSON.parse(jsonBodyStr)
jsonBody.forEach(function(item){
if(!item.disabled){
arr.push(item.key)
map[item.key] = item.value
}
})
}
Re: code "1004", msg "sign invalid"
Posted: 2023年 Oct 31日 16:28
by adiot
Thank you for your answer. However, the environment configuration is normal no matter how much I check.
What's strange is that even though Tuya API Explorer and PostMan used the same Timestamp value, the HMAC value was different.
Obviously, ClientID, Secret, and Timestamp values are the same, so why are HMAC values different?
Re: code "1004", msg "sign invalid"
Posted: 2023年 Oct 31日 16:37
by adiot
Thank you. There was a problem with the pre-scripte.
The new download solved the problem.
Is the previous download the past version.. It's..
Anyway, thanks to you, I solved it. Thank you.