# Node-red-contrib-netatmo 0.3.0: Error: Authenticate error: unauthorized\_client

**URL:** <https://discourse.nodered.org/t/node-red-contrib-netatmo-0-3-0-error-authenticate-error-unauthorized-client/79952>\
**Category:** General\
**Created:** [20 July 2023 06:29 UTC](https://discourse.nodered.org/t/node-red-contrib-netatmo-0-3-0-error-authenticate-error-unauthorized-client/79952 "2023-07-20T06:29:00Z")\
**Posts on this page:** 1\
**Showing post:** 24

<div class="post-metadata">

**Author:** ![bakman2](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bakman2/32/6207_2.png) [@bakman2](https://discourse.nodered.org/u/bakman2)\
**Post date:** [4 August 2023 12:18 UTC](https://discourse.nodered.org/t/node-red-contrib-netatmo-0-3-0-error-authenticate-error-unauthorized-client/79952/24 "2023-08-04T12:18:30Z")

</div>

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](https://flows.nodered.org/node/node-red-contrib-oauth2) node, which made this relatively easy, as it provides an interface to setup the access.

Example flow (still requires one-time fiddling)

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/9/d/9d45b64f67c96e7c698d1bfde81eead3461c70ce.png)

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/9/0/90e0a2fa7addf6ce5b33265748583356bda225cc.png)  
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.

```auto
[{"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}]

```

---

_[View the full topic](https://discourse.nodered.org/t/node-red-contrib-netatmo-0-3-0-error-authenticate-error-unauthorized-client/79952)._
