hassio-addons / addon-grocy

Grocy - Home Assistant Community Add-ons
https://addons.community
MIT License
319 stars 60 forks source link

Unable to access the API for Grocy through HA. #310

Closed huxoll closed 2 years ago

huxoll commented 2 years ago

Problem/Motivation

I want to use the API, but all I get is 401.

Expected behavior

Calling a command like: curl -X 'GET' \ 'http://homeassistant:8123/api/hassio_ingress/{md5-omitted}/api/objects/batteries' \ -H 'accept: application/json' \ -H 'GROCY-API-KEY: {key-ommitted}' \ -H "Authorization: Bearer {bearertoken-omitted}" should work.

Actual behavior

From the command line, I get: 401: Unauthorized%
However, calling plain HA API works: curl -X 'GET' \ 'http://homeassistant:8123/api/core/check_config' \ -H 'accept: application/json' \ -H 'GROCY-API-KEY: {key-ommitted}' \ -H "Authorization: Bearer {bearertoken-omitted}" Also, the API browser works. Is there something more to get to the Grocy API?

Steps to reproduce

(How can someone else make/see it happen)

My installation is Home Assistant OS on a Raspberry PI, core-2022.6.7 Home Assistant OS 8.4 Grocy (0.18.2)

sinclairpaul commented 2 years ago

The ingress function of HA requires an authenticated session. I would suggest you expose the addon on a port and try it from that.

frenck commented 2 years ago

@huxoll, it is correct what @sinclairpaul states.

Go to the add-on configuration tab of the Grocy in Home Assistant, assign a port in the network settings. Restart the add-on.

You can now access Grocy directly on that port.

../Frenck

nuk3man commented 2 years ago

I'm having a similar issue with Grocy running on Pi4 HA. It works fine with the Gorcy custom integration. However, when I try to setup the following sensor I get error 401 unauthorized:

  name: grocy_main
  resource: https://XXX.ui.nabu.casa/api/hassio_ingress/XXX/api/stock/entry/2
  method: GET
  json_attributes:
    - stock_amount
  headers:
    accept: application/json
    Content-Type: application/json
    GROCY-API-KEY: !secret grocy_api
    authorization: LONG-LASTING TOKEN

I've tried changing the resource to the following:

resource: https://192.168.1.219:9192/api/stock/entry/2
resource: http://192.168.1.219:9192/api/stock/entry/2
http://homeassistant.local:8123/api/hassio_ingress/XXX/api/stock/entry/1
http://homeassistant.local:9192/api/hassio_ingress/X/api/stock/entry/1

Any suggestions on how to fix it? (The port has been forwarded on my router)

huxoll commented 2 years ago

I can confirm the following command works for me, with 8888 added as an additional network port on the Grocy configuration. I can get to the login page, but the only authentication I believe is for the API.

curl -X 'GET' 'https://hassio:8888/api/stock' -H 'accept: application/json' -H 'GROCY-API-KEY: {redacted}'

You might try it from the command line first and validate it's working before using as a sensor.

nuk3man commented 2 years ago

Thanks for the reply. I opened up port 8888 on my router (and set the Grocy port to 8888) and tried the command, resulting in the following error:

curl: (7) Failed to connect to hassio port 8888 after 1 ms: Connection refused.

huxoll commented 2 years ago

That was my port number (8888); you'll need to choose your own. This is a new port not already used by hassio. The description could be better, I think. It's not actually changing a port, it's exposing a new port for the Grocy interface.

Here's where you set it. grocy_external_port

nuk3man commented 2 years ago

Thanks. That's actually where I also set it to 8888 (after previously trying 9192), but still gives the same error.

huxoll commented 2 years ago

Hmmm, curious. It works for me. I suggest adding a couple of "-v" options to your curl command to verify that there are no surprises in host resolution or SSL certificate. (Also, in the error message you used hassio, which was the placeholder I used; I assume you're using your real host name.)

Otherwise, it seems like it's blocked by a router or firewall.

You can run it in the terminal directly on the web interface with a command like this: curl "https://homecontrol.local:8888/api/stock" --insecure -v -v -H 'accept: application/json' -H 'GROCY-API-KEY: {redacted}'

nuk3man commented 2 years ago

That seems to have done the trick (I think?). I removed the s from https and got the following output:

*   Trying 192.168.1.220:8888...
* Connected to 192.168.1.220 (192.168.1.220) port 8888 (#0)
> GET /api/stock HTTP/1.1
> Host: 192.168.1.220:8888
> User-Agent: curl/7.83.1
> accept: application/json
> GROCY-API-KEY: {redacted}
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 401 Unauthorized
< Server: nginx
< Date: Mon, 22 Aug 2022 18:32:40 GMT
< Content-Type: text/html; charset=UTF-8
< Transfer-Encoding: chunked
< Connection: keep-alive
< X-Powered-By: PHP/8.0.20
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
< Access-Control-Allow-Headers: *
< 
* Connection #0 to host 192.168.1.220 left intact

How would I add --insecure to my hassio script? Do I just add "insecure" under headers?

huxoll commented 2 years ago

It looks like you don't have SSL enabled? You'll need to either remove https from your URL if you haven't set up SSL certificates, or if you are, you have to use the correct SSL domain name.

If you're not using SSL, you don't need the "--insecure" option, that's only required in my last example because the hostname didn't resolve correctly from that terminal, and I am using SSL.

nuk3man commented 2 years ago

It looks like you don't have SSL enabled? You'll need to either remove https from your URL if you haven't set up SSL certificates, or if you are, you have to use the correct SSL domain name.

If you're not using SSL, you don't need the "--insecure" option, that's only required in my last example because the hostname didn't resolve correctly from that terminal, and I am using SSL.

That's correct, I disabled SSL to have minimum interference while trying to solve it. I'm not really sure how to set up a certificate for this anyway so I'll leave it be for the time being.

The last line ('* Connection #0 to host 192.168.1.220 left intact') leads me to believe the connection has been established and is ok. Is this correct? Because when I use the same credentials in my sensor it doesn't work.

huxoll commented 2 years ago

The connection was physically opened, but notice the return code.

In the snippet you supplied, it was a 401 return code, which corresponds to unauthorized. HTTP/1.1 401 Unauthorized

In this case, this probably means the API key is incorrect.

nuk3man commented 2 years ago

I did see that but thought that the last line ("* Connection #0 to host 192.168.1.220 left intact") indicated that somehow the connection had still been established. As for the API-key; I just copied the key straight from Grocy. I'm starting to think I've missed something very obvious because I'm running out of options really.

nuk3man commented 2 years ago

The connection was physically opened, but notice the return code.

In the snippet you supplied, it was a 401 return code, which corresponds to unauthorized. HTTP/1.1 401 Unauthorized

In this case, this probably means the API key is incorrect.

That was indeed the case. It was so obvious I missed it. I forgot the remove the curly brackets around the API key.