Page 1 of 1

Cannot get sign authorized in browser with vanilla JS

Posted: 2023年 Dec 15日 09:49
by Marty McFly

I am working on this for my private home network so security is not really an issue. I'm trying to get sign authorized through a browser, using an HTML file with vanilla JavaScript. I thought this was all I need but I keep getting "sign invalid" and I can't figure out why....

I keep getting "sign invalid" and I can't figure out why. I would gladly buy someone a beer or coffee if you can tell me where I'm going wrong?

I should mention that I am able to get authorized in Postman, the Tuya API explorer and Node.js. The code below is the modified Node.js code...

Code: Select all

var ClientID = 'xxxxxxxxxxxxxxxxx';
var secretKey = 'xxxxxxxxxxxxxxxxxxxxxxxxxxx';

getToken();

async function getToken(){
	
  var method = 'GET';
  var timestamp = Date.now().toString();
  var signUrl = '/v1.0/token?grant_type=1';
  var contentHash = CryptoJS.HmacSHA256(signStr, secretKey);
  var stringToSign = [method, contentHash, '', signUrl].join('\n');
  var signStr = ClientID + timestamp + stringToSign;

  console.log(await encryptStr(signStr, secretKey));
	
fetch('https://openapi.tuyaus.com//v1.0/token?grant_type=1', {
	method: 'GET',
	headers: {
		't': timestamp,
		'sign_method': 'HMAC-SHA256',
		'client_id': ClientID,
		'sign': await encryptStr(signStr, secretKey)

	},
}).then(function(response) {var json = response.json();console.log(json);})
}

async function encryptStr(signStr, secretKey) {
  var hash = CryptoJS.HmacSHA256(signStr, secretKey);
  var hashInBase64 = hash.toString().toUpperCase();
  return hashInBase64;
}

Re: Cannot get sign authorized in browser with vanilla JS

Posted: 2023年 Dec 15日 14:33
by panda-cat

hi, after checking your script, I found that the contentHash processing is incorrect. It should be SHA256, not HmacSHA256. Please check: https://developer.tuya.com/en/docs/iot/ ... 5g#title-4 -Content-SHA256


Re: Cannot get sign authorized in browser with vanilla JS

Posted: 2023年 Dec 16日 12:20
by Marty McFly

edit


Re: Cannot get sign authorized in browser with vanilla JS

Posted: 2023年 Dec 16日 13:04
by Marty McFly
panda-cat 2023年 Dec 15日 14:33

hi, after checking your script, I found that the contentHash processing is incorrect. It should be SHA256, not HmacSHA256. Please check: https://developer.tuya.com/en/docs/iot/ ... 5g#title-4 -Content-SHA256

Wow! What an amazing eye! Thank you so much @panda-cat. That works great and now I can get a token! Can you send me a PayPal address so I can send you a little something? Thank you so much!!

I'm so sorry but I do have a new problem now. I've been trying all night and I cannot get signed when authorizing this 'POST' command....

Code: Select all

			async function TurnLightOff(deviceId) {
			  var timestamp2 = Date.now().toString();
			  var signUrl2 = '/v1.0/devices/xxxxxxxxxxxxxxx/commands';
			  var contentHash2 = CryptoJS.SHA256(signStr2, secretKey);
			  var stringToSign2 = [method2, contentHash2, '', signUrl2].join('\n');
			  var signStr2 = ClientID + token + timestamp2 + stringToSign2;

			fetch('https://openapi.tuyaus.com//v1.0/devices/xxxxxxxxxxxxxxxxxx/commands', {
				method: 'POST',
				headers: {
					't': timestamp2,
					'sign_method': 'HMAC-SHA256',
					'Content-Type': 'application/json',
					'client_id': ClientID,
					'sign': await calcSign(signStr2, secretKey),
					'access_token': token
				},
				body: JSON.stringify({
						"commands": [
						  {
							"code": "switch_1",
							"value": false
						  }
						]
			  })
			}).then(response => response.json()) 
				.then((data) => {console.log(data)});

		}
		
async function calcSign(signStr2, secretKey){
  var hash2 = CryptoJS.HmacSHA256(signStr2, secretKey);
  var hashInBase642 = hash2.toString().toUpperCase()
  return hashInBase642;
}