-
Notifications
You must be signed in to change notification settings - Fork 602
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SUPERVISOR_TOKEN for addon websocket connection isn't working #5028
Comments
I found the reason for my "strange things no 2": On the Pi5 I used the "Terminal and SSH" addon, on the Pi4 the "Advanced SSH and Web Terminal" addon. I switched to the latter on my Pi5 and got the working token typing 'printenv SUPERVISOR_TOKEN'. However, the behavior is weird. Under which circumstance supervisor tokens are generated? |
I can't seem to replicate your error, how exactly have you implemented the method for websocket connections? |
Hi Erik
Thanks for looking at the issue.
I initialize my handler with:
self.auth_token: str | None = os.getenv("SUPERVISOR_TOKEN")
self._uri = "ws://supervisor/core/websocket"
Later I open the websocket with
self.websck = await websockets.connect(
self._uri,
extra_headers={
"Authorization": f"Bearer {self.auth_token}",
"Content-Type": "application/json",
},
open_timeout=1,
)
The next step is
resp = await self.websck.recv()
if json.loads(resp)["type"] == "auth_required":
try:
msg = WEBSOCK_MSG.auth_msg
msg["access_token"] = self.auth_token
await self.websck.send(json.dumps(msg))
resp = await self.websck.recv()
self.logger.info(
f"Websocket connecting to {self._uri}, response: {resp}"
)
if json.loads(resp)["type"] == "auth_invalid":
self.logger.error(f"Websocket authentification failed: {json.
loads(resp)['message']}")
await self.close_websocket()
return False
except Exception as err_msg:
self.logger.error(f"Websocket authentification failed: {err_msg}")
await self.close_websocket()
self.token_ok = False
return False
If this step fails (never, if I run it als a locally built addon, always,
if installed from ghcr.io), I pick the SUPERVISOR_TOKEN from file, which I
got from the 'Advanced SSH & Web Terminal'-addon with print_env
SUPERVISOR_TOKEN > def_token.def. This one works fine.
It seems to me as if the token generated for my addon isn't the one against
the authentification procedure checks.
Do you need more details?
Here my config.yaml:
---
name: "Smart Hub"
description: "Habitron Smart Hub as Home Assistant Add-on"
version: 1.1.9
slug: "smart_hub"
arch:
- aarch64
ports:
7777/udp: 7777
startup: services
init: false
full_access: false
hassio_api: true
host_network: true
map: [addon_config:rw]
devices: ["dev/serial0"]
uart: true
devicetree: true
ingress: true
panel_title: Habitron Smart Hub
panel_icon: hbt:habitron-logo
panel_admin: true
image: "ghcr.io/dneprojects/smart_hub/{arch}"
Thanks for helping me! If you have an idea, which I can check, please don't
hesitate to contact me.
Best regards, Dietmar
Am Di., 23. Apr. 2024 um 10:32 Uhr schrieb Erik ***@***.***>:
… I can't seem to replicate your error, how exactly have you implemented the
method for websocket connections?
—
Reply to this email directly, view it on GitHub
<#5028 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/A5VKTZXHCZ7OP73IHO7KYFLY6YMAHAVCNFSM6AAAAABGO6FLGGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDANZRG4ZDOOBQGI>
.
You are receiving this because you authored the thread.Message ID:
***@***.***>
|
I forgot to include the definition of the auth_msg:
auth_msg = {"type": "auth", "access_token": ""}
Thanks, Dietmar
Am Di., 23. Apr. 2024 um 12:09 Uhr schrieb dne.projects <
***@***.***>:
… Hi Erik
Thanks for looking at the issue.
I initialize my handler with:
self.auth_token: str | None = os.getenv("SUPERVISOR_TOKEN")
self._uri = "ws://supervisor/core/websocket"
Later I open the websocket with
self.websck = await websockets.connect(
self._uri,
extra_headers={
"Authorization": f"Bearer {self.auth_token}",
"Content-Type": "application/json",
},
open_timeout=1,
)
The next step is
resp = await self.websck.recv()
if json.loads(resp)["type"] == "auth_required":
try:
msg = WEBSOCK_MSG.auth_msg
msg["access_token"] = self.auth_token
await self.websck.send(json.dumps(msg))
resp = await self.websck.recv()
self.logger.info(
f"Websocket connecting to {self._uri}, response: {resp}"
)
if json.loads(resp)["type"] == "auth_invalid":
self.logger.error(f"Websocket authentification failed: {json.
loads(resp)['message']}")
await self.close_websocket()
return False
except Exception as err_msg:
self.logger.error(f"Websocket authentification failed: {err_msg}")
await self.close_websocket()
self.token_ok = False
return False
If this step fails (never, if I run it als a locally built addon, always,
if installed from ghcr.io), I pick the SUPERVISOR_TOKEN from file, which
I got from the 'Advanced SSH & Web Terminal'-addon with print_env
SUPERVISOR_TOKEN > def_token.def. This one works fine.
It seems to me as if the token generated for my addon isn't the one
against the authentification procedure checks.
Do you need more details?
Here my config.yaml:
---
name: "Smart Hub"
description: "Habitron Smart Hub as Home Assistant Add-on"
version: 1.1.9
slug: "smart_hub"
arch:
- aarch64
ports:
7777/udp: 7777
startup: services
init: false
full_access: false
hassio_api: true
host_network: true
map: [addon_config:rw]
devices: ["dev/serial0"]
uart: true
devicetree: true
ingress: true
panel_title: Habitron Smart Hub
panel_icon: hbt:habitron-logo
panel_admin: true
image: "ghcr.io/dneprojects/smart_hub/{arch}
<http://ghcr.io/dneprojects/smart_hub/%7Barch%7D>"
Thanks for helping me! If you have an idea, which I can check, please
don't hesitate to contact me.
Best regards, Dietmar
Am Di., 23. Apr. 2024 um 10:32 Uhr schrieb Erik ***@***.***
>:
> I can't seem to replicate your error, how exactly have you implemented
> the method for websocket connections?
>
> —
> Reply to this email directly, view it on GitHub
> <#5028 (comment)>,
> or unsubscribe
> <https://github.com/notifications/unsubscribe-auth/A5VKTZXHCZ7OP73IHO7KYFLY6YMAHAVCNFSM6AAAAABGO6FLGGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDANZRG4ZDOOBQGI>
> .
> You are receiving this because you authored the thread.Message ID:
> ***@***.***>
>
|
I'm seeing this too: config.yaml:
Dockerfile:
run.sh:
Log:
|
I've spent the better part of today trying to get this working. 31 tries in and still no dice. I've tried every relevant config.yaml option, older base images, rebooting, you name it. No matter what I do I never see this env var in my container. I have the ssh addon and I can echo the token there so other addons seem to get it, I just can't figure out why I don't. The main difference is mine is local in /addons but not sure why that would matter. It shows up in the UI, updating version in config.yaml and looking for updates in the UI shows it, it installs and runs fine, everything seems normal. But no token. Interestingly, when I grab the token from the ssh addon and use it in my code to connect to websockets I get an auth_invalid response. Had to resort to using a long-lived as a workaround for now. /sad panda |
Hi
First, you need to add the line
hassio_api: true
to your config.yaml.
I'm not sure whether this is needed in your case. In order to get access to
the token inside the container, the first line in the shell script should be
#!/usr/bin/with-contenv sh
I hope this helps...
Best wishes, Dietmar
grahamj ***@***.***> schrieb am Mo., 6. Mai 2024, 02:10:
… I've spent the better part of today trying to get this working. 31 tries
in and still no dice. I've tried every relevant config.yaml option, older
base images, rebooting, you name it. No matter what I do I never see this
env var in my container.
I have the ssh addon and I can echo the token there so other addons seem
to get it, I just can't figure out why I don't. The main difference is mine
is local in /addons but not sure why that would matter. It shows up in the
UI, updating version in config.yaml and looking for updates in the UI shows
it, it installs and runs fine, everything seems normal. But no token.
Interestingly, when I grab the token from the ssh addon and use it in my
code to connect to websockets I get an auth_invalid response. Had to resort
to using a long-lived as a workaround for now.
/sad panda
—
Reply to this email directly, view it on GitHub
<#5028 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/A5VKTZTLIJNRAXYLE4EG5ALZA3DALAVCNFSM6AAAAABGO6FLGGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDAOJVGAYTAMBVGQ>
.
You are receiving this because you authored the thread.Message ID:
***@***.***>
|
OMG the shebang worked, thank you so much! I had it in there at one point before but something else must have been wrong. Wow the docs really need to make more clear how critical that is! |
You are right, the documentation is really bad! I faced another problem after I solved that one you had. The code seems to be very sensitive to timings:
I don't understand, why, but if I used the supervisor_token from the "Advanced SSH & Web terminal"-addon, the code worked without the delay and also with a timeout of 1s. The timeout value was also dependent on the type of Raspi I was using: on a Pi4 I succeeded with 2s, on a Pi5 I needed 3s. This is why I feel, the code must be buggy! |
yeah you should not need to sleep for sure. My Python is pretty rusty (my addon is actually a shim to write automations in nodejs!) but I can tell you that in Node I don't have any issues connecting to websockets 🤷♂️ |
There hasn't been any activity on this issue recently. Due to the high number of incoming GitHub notifications, we have to clean some of the old issues, as many of them have already been resolved with the latest updates. |
Describe the issue you are experiencing
I have an addon written in Python code, which opens a websocket connection to HA in order to call a service.
In the addon I get the token by the command 'os.getenv("SUPERVISOR_TOKEN")'.
With that token I connect: 'websockets.connect("ws://supervisor/core/websocket",extra_headers={"Authorization": f"Bearer {bearer_token}"}' .
In the next strep, the server sends a message '{"type":"auth_required","ha_version":"2024.4.3"}',
my addon responds with '{"type": "auth", "access_token": "788dba363765f...184e6f8c21acc2415dc43"}' with the SUPERVISOR_TOKEN.
The server replys '{"type":"auth_invalid","message":"Invalid access"}' and closes the connection.
I think, the procedure is OK, but the token is wrong. There are more strange things:
On the Pi 5 this workaround does not help.
It seems as if the internal handling of the tokens is out of order...
What type of installation are you running?
Home Assistant OS
Which operating system are you running on?
Home Assistant Operating System
Steps to reproduce the issue
'supervisor_token = os.getenv("SUPERVISOR_TOKEN")'
...
Anything in the Supervisor logs that might be useful for us?
System Health information
This is taken from my addon logs:
2024-04-19 12:38:52 DEBUG websockets.client: = connection is CONNECTING
2024-04-19 12:38:52 DEBUG websockets.client: > GET /core/websocket HTTP/1.1
2024-04-19 12:38:52 DEBUG websockets.client: > Host: supervisor
2024-04-19 12:38:52 DEBUG websockets.client: > Upgrade: websocket
2024-04-19 12:38:52 DEBUG websockets.client: > Connection: Upgrade
2024-04-19 12:38:52 DEBUG websockets.client: > Sec-WebSocket-Key: 6mWZuuqIfqnVlzrBMRem3Q==
2024-04-19 12:38:52 DEBUG websockets.client: > Sec-WebSocket-Version: 13
2024-04-19 12:38:52 DEBUG websockets.client: > Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
2024-04-19 12:38:52 DEBUG websockets.client: > Authorization: Bearer 80b41982adf8b6d08d983120a4445d11bec099e5e6f0d3c1e4789d6808eea627daf952ad03789680e1fa24faf77abcadf62191922a3bff5a
2024-04-19 12:38:52 DEBUG websockets.client: > User-Agent: Python/3.11 websockets/12.0
2024-04-19 12:38:52 DEBUG websockets.client: < HTTP/1.1 101 Switching Protocols
2024-04-19 12:38:52 DEBUG websockets.client: < Upgrade: websocket
2024-04-19 12:38:52 DEBUG websockets.client: < Connection: upgrade
2024-04-19 12:38:52 DEBUG websockets.client: < Sec-WebSocket-Accept: +F5BKQQ50hTwu+2j0ImYx4iKQ+M=
2024-04-19 12:38:52 DEBUG websockets.client: < Sec-WebSocket-Extensions: permessage-deflate
2024-04-19 12:38:52 DEBUG websockets.client: < Date: Fri, 19 Apr 2024 10:38:52 GMT
2024-04-19 12:38:52 DEBUG websockets.client: < Server: Python/3.12 aiohttp/3.9.3
2024-04-19 12:38:52 DEBUG websockets.client: = connection is OPEN
2024-04-19 12:38:52 DEBUG websockets.client: < TEXT '{"type":"auth_required","ha_version":"2024.4.3"}' [48 bytes]
2024-04-19 12:38:52 DEBUG websockets.client: > TEXT '{"type": "auth", "access_token": "80b41982adf8b...abcadf62191922a3bff5a"}' [148 bytes]
2024-04-19 12:38:52 DEBUG websockets.client: < TEXT '{"type":"auth_invalid","message":"Invalid access"}' [50 bytes]
2024-04-19 12:38:52 DEBUG websockets.client: < CLOSE 1000 (OK) [2 bytes]
2024-04-19 12:38:52 DEBUG websockets.client: = connection is CLOSING
2024-04-19 12:38:52 DEBUG websockets.client: > CLOSE 1000 (OK) [2 bytes]
2024-04-19 12:38:52 DEBUG websockets.client: = connection is CLOSED
Supervisor diagnostics
config_entry-hassio-393b944bf81b49e9dbad4d65c5ee4e8f.json
Additional information
HA Core 2024.4.3, HA Supervisor 2024.04.0, HAOS 12.2
The text was updated successfully, but these errors were encountered: