Possibility to authenticate without calculating the sign every time?
Current Situation
Hello, I'm writing Javascript code that will run on an esp32-based device. I don't have a lib to calculate the sign every time I want to send a request. Is it possible to calculate it once and reuse it for several requests?
Logs
If I use an already generated sign (together with the nonce, t, Authorization key), I get `statusCode: 401
{"message":"Unauthorized"}` on every request, if I edit the script to calculate the sign just before sending it, it works.
Configuration
`auth` - contains already generated sign, Authorization key, nonce, and t (same as when the sign is generated)
const options = {
hostname: 'api.switch-bot.com',
port: 443,
path: `/v1.1/devices/`,
method: 'GET',
headers: {
...auth,
'Content-Type': 'application/json',
'Content-Length': 0,
},
};
const req = https.request(options, res => {
console.log(`statusCode: ${res.statusCode}`);
res.on('data', d => {
process.stdout.write(d);
});
});
req.on('error', error => {
console.error(error);
});
Environment
- OS: MacOS
- Software: Node
- Node: v20.16.0
- npm: 10.8.2
Additional Context
No response
You could proxy the request via another server, if needed. Although, I can see why you'd want to keep everything on device. From my understanding, this is very much a required part of the headers sent with your request. I use python, and use this function to auth.
Edit: Since the sign contains timestamp of the request, you'd need to generate it everytime, as otherwise the switchbot API, likely within a margin of a few seconds, or a minute will invalidate your request. I doubt they'll change this.
def prepare_header():
nonce = str(uuid.uuid4())
timestamp = str(int(round(time.time() * 1000)))
string_to_sign = f"{TOKEN}{timestamp}{nonce}"
bytes_to_sign = bytes(string_to_sign, "utf-8")
secret_bytes = bytes(SECRET, "utf-8")
signature = hmac.new(
secret_bytes, msg=bytes_to_sign, digestmod=hashlib.sha256
).digest()
encoded_signature = base64.b64encode(signature).decode("utf-8")
apiHeader = {
"Authorization": TOKEN,
"Content-Type": "application/json",
"charset": "utf-8",
"t": timestamp,
"sign": encoded_signature,
"nonce": nonce,
}
return apiHeader