Node-red-contrib-netatmo 0.3.0: Error: Authenticate error: unauthorized_client

I have said it before - oauth2 is horrible. Would be nice if it could be integrated into the http request node (somehow), especially with so many applications using it today and it requires a browser for interaction with the api provider to provide scoped access.

What I used with the old node and still miss in the new node is the ability to read public data from other Netatmo installations, which I used to get rain information in my area.

I had the same issue. Instead I installed the node-red-oauth2 node, which made this relatively easy, as it provides an interface to setup the access.

Example flow (still requires one-time fiddling)


In the authorization code node provide the

clientid
client secret

Click the key button, it will open a window to netatmo, ok for access, window will close
now the code has been filled in, done
deploy
press the inject button

Access token and refresh token are saved as a global object

Now you can access the public data url (make sure to modify the url inside the function node)
Adjust the credentials function node to refresh the token automatically every 55 mins.

[{"id":"cb7f83d9a367348a","type":"inject","z":"225edc0f2ab084a8","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":160,"y":260,"wires":[["2514d8dc875c1b2e"]]},{"id":"990b3fc65eb5a01c","type":"http request","z":"225edc0f2ab084a8","name":"","method":"GET","ret":"obj","paytoqs":"ignore","url":"","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"","senderr":false,"headers":[],"credentials":{},"x":445,"y":260,"wires":[["8c7095a7361d00b6"]],"l":false},{"id":"2514d8dc875c1b2e","type":"function","z":"225edc0f2ab084a8","name":"get public data","func":"const access_token = global.get('netatmo_oauth2').token.access_token\nconst headers = {}\nconst types = [\"rain\", \"wind\"]\n\nheaders[\"Authorization\"] = `Bearer ${access_token}`\n\nlet url = \"https://api.netatmo.com/api/getpublicdata?lat_ne=52.147605%20&lon_ne=4.473581&lat_sw=52.108087&lon_sw=4.435644&filter=false\"\n\ntypes.forEach(type=>{\n    url = `${url}&required=${type}`\n    node.send({headers,url})\n})\n\n\nreturn null","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":320,"y":260,"wires":[["990b3fc65eb5a01c"]]},{"id":"8c7095a7361d00b6","type":"debug","z":"225edc0f2ab084a8","name":"debug 383","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":550,"y":260,"wires":[]},{"id":"592dc8f750c3cd36","type":"group","z":"225edc0f2ab084a8","name":"setup credentials","style":{"label":true},"nodes":["9909b6f7dfd95f9f","1ef7250fbe8d2af9","7c6ab1c7a02690d4","6f5aed0bdbad1cae","8198db5e0cfcb195","e1fbe19cb319629c","cdab0b5dadd0e33e","8251478843e59995","28a02df4e332b227"],"x":54,"y":59,"w":642,"h":142},{"id":"9909b6f7dfd95f9f","type":"oauth2","z":"225edc0f2ab084a8","g":"592dc8f750c3cd36","name":"Authorization Code","container":"oauth2Response","grant_type":"authorization_code","access_token_url":"https://api.netatmo.com/oauth2/token","authorization_endpoint":"https://api.netatmo.com/oauth2/authorize","redirect_uri":"/oauth2/redirect_uri","open_authentication":"","username":"","password":"","client_id":"","client_secret":"","scope":"read_station","proxy":"","senderr":false,"client_credentials_in_body":false,"rejectUnauthorized":true,"headers":{},"x":330,"y":100,"wires":[["e1fbe19cb319629c"]]},{"id":"1ef7250fbe8d2af9","type":"inject","z":"225edc0f2ab084a8","g":"592dc8f750c3cd36","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":160,"y":100,"wires":[["9909b6f7dfd95f9f"]]},{"id":"7c6ab1c7a02690d4","type":"inject","z":"225edc0f2ab084a8","g":"592dc8f750c3cd36","name":"Refresh Token","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"3300","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":180,"y":160,"wires":[["8251478843e59995"]]},{"id":"6f5aed0bdbad1cae","type":"oauth2","z":"225edc0f2ab084a8","g":"592dc8f750c3cd36","name":"Set by msg.oauth2Request","container":"oauth2Response","grant_type":"set_by_credentials","access_token_url":"http://localhost:3000/oauth/token ","username":"pedroet","password":"","client_id":"confidentialApplication","client_secret":"topSecret","scope":"*","headers":{},"x":455,"y":160,"wires":[["28a02df4e332b227"]],"l":false},{"id":"8198db5e0cfcb195","type":"debug","z":"225edc0f2ab084a8","g":"592dc8f750c3cd36","name":"DBG 2","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":600,"y":160,"wires":[]},{"id":"e1fbe19cb319629c","type":"function","z":"225edc0f2ab084a8","g":"592dc8f750c3cd36","name":"Set refreshToken","func":"const access_token_url = \"https://api.netatmo.com/oauth2/token\"\n\nif (msg.oauth2Response.access_token) {\n    const netatmo_oauth2 = {}\n    netatmo_oauth2.url = access_token_url\n    netatmo_oauth2.token = msg.oauth2Response\n\n    global.set(\"netatmo_oauth2\", netatmo_oauth2)\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":455,"y":100,"wires":[["cdab0b5dadd0e33e"]],"l":false},{"id":"cdab0b5dadd0e33e","type":"debug","z":"225edc0f2ab084a8","g":"592dc8f750c3cd36","name":"DBG 1","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":550,"y":100,"wires":[]},{"id":"8251478843e59995","type":"function","z":"225edc0f2ab084a8","g":"592dc8f750c3cd36","name":"credentials","func":"let netatmo = global.get('netatmo_oauth2');\n\nmsg.oauth2Request = { \n    \"access_token_url\": netatmo.url,\n    \"credentials\": {\n        \"grant_type\": \"refresh_token\",\n        \"client_id\": \"\",\n        \"client_secret\": \"\",\n        \"scope\": \"read_station\",\n        \"refresh_token\": netatmo.token.refresh_token   \n    },\n};\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":350,"y":160,"wires":[["6f5aed0bdbad1cae"]]},{"id":"28a02df4e332b227","type":"function","z":"225edc0f2ab084a8","g":"592dc8f750c3cd36","name":"Set refreshToken","func":"const access_token_url = \"https://api.netatmo.com/oauth2/token\"\n\nif (msg.oauth2Response.access_token) {\n    const netatmo_oauth2 = {}\n    netatmo_oauth2.url = access_token_url\n    netatmo_oauth2.token = msg.oauth2Response\n\n    global.set(\"netatmo_oauth2\", netatmo_oauth2)\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":505,"y":160,"wires":[["8198db5e0cfcb195"]],"l":false}]
1 Like