Rest Authentication Sensor

I have a sensor that gets an authentication token:

sensor rest_token:
  - platform: rest
    name: rest_token
    method: POST
    scan_interval: 3600
    resource: http://192.168.1.13:8081/app/rest/v2/oauth/token?grant_type=password&username=XXXXX&password=XXXXX
    value_template: '{{"Bearer "+ value_json.access_token}}'
    headers:
      Authorization: Basic Y2xpZW50OnNlY3JldA==
      Content-Type: application/x-www-form-urlencoded

What I am trying to do is either. Update the !secret with the token or use the sensor token like follows:

sensor rest:
  - platform: rest
    name: Uninvoiced Spend
    resource: http://192.168.1.13:8081/app/rest/v2/services/some_service/getSomeValue
    value_template: '{{ value_json|float|round(2) *-1 }}'
    unit_of_measurement: "c"
    headers:
      Authorization: '{{ states("sensor.rest_token") }}'

I cannot get this to work.

I can get it to work if I set a value in the secrets file e.g.

sensor rest:
  - platform: rest
    name: Uninvoiced Spend
    resource: http://192.168.1.13:8081/app/rest/v2/services/some_service/getSomeValue
    value_template: '{{ value_json|float|round(2) *-1 }}'
    unit_of_measurement: "c"
    headers:
      Authorization: !secret rest_token 

But the problem is that I need to update the token every couple of hours.

Getting the token works. If I go to Developer -> States -> rest_token I can see the correct value and the token updating. I am just trying to figure out how to get that value into the other rest sensors authentication variable.

Any suggestions would be appreciated.

1 Like

Unfortunately this won’t work, because the headers can only be strings, not templates.

I’m not aware of any way to accomplish what you are trying to do inside Home Assistant. Does your server support any other authentication method, or supports adding the token as URL parameter?

And as a side note: it would probably have been better to share your progress on this topic on your previous post from 2 days ago, instead of asking almost the same question again in a new post.

After a lot of mucking around I have managed to figure it out.

Step 1: Create a secret in secrets.yaml

# Use this file to store secrets like usernames and passwords.
# Learn more at https://www.home-assistant.io/docs/configuration/secrets/
some_password: welcome
rest_token:

Step 2: Create a command_line sensor which updates the secrets.yaml rest_token value

This step was a lot of mucking around trying to convert the command to something yaml would accept

sensor rest_token:
  - platform: command_line
    name: rest_token
    scan_interval: 36000 # every 10 hours
    command: 'json=$(curl --location --request POST ''http://192.168.1.13:8081/app/rest/v2/oauth/token'' --header ''Authorization: Basic XXXXYYYYYY=='' --header ''Content-Type: application/x-www-form-urlencoded'' --data-urlencode ''grant_type=password'' --data-urlencode ''username=USERNAME'' --data-urlencode ''password=PASSWORD'' | jq -r ''.access_token'') && echo $json && sed -i "s/\(rest_token:\)\(.*\)/\1 Bearer $json/" /config/secrets.yaml && ha core restart'

Actual shell command (for testing via ssh):
You should get the access token printed to the terminal screen and the secrets.yaml rest_token value updated

json=$(curl --location --request POST 'http://192.168.1.13:8081/app/rest/v2/oauth/token' --header 'Authorization: Basic XXXXYYYYYXXXX==' --header 'Content-Type: application/x-www-form-urlencoded' --data-urlencode 'grant_type=password' --data-urlencode 'username=USERNAME' --data-urlencode 'password=PASSWORD' | jq -r '.access_token') && echo $json && sed -i "s/\(rest_token:\)\(.*\)/\1Bearer $json/" /config/secrets.yaml && ha core restart

secrets.yaml:
rest_token: Bearer 2c9b3230-2446-46f8-84d1-bfb7085e3311

Step 3: Create rest sensors using token from secrets file

sensor rest:
  - platform: rest
    name: Name1
    resource: http://192.168.1.13:8081/app/rest/v2/services/someService/getSomeValue?account=186a59d6-67d3-b998-f3d0-a1e5e91b9a42
    value_template: '{{ value_json|float|round(2) *-1 }}'
    unit_of_measurement: "c"
    headers:
      Authorization: !secret rest_token
  - platform: rest
    name: Name2
    resource: http://192.168.1.13:8081/app/rest/v2/services/someOtherService?value=SOMEVALUE
    value_template: '{{ value_json.price|float|round(1) }}'
    unit_of_measurement: "c"
    headers:
      Authorization: !secret rest_token

edit:
needed command [&& ha core restart] to be added to command in rest_token to restart ha after token update so the rest sensors use the new token secret.

This looks like a valid solution to your problem. But it’s a bit brutal to force restart HA every time.

Isn’t it possible to store the token in a variable somewhere and use this in the address which is stored in the secrets.yaml file?

1 Like

I’m looking to sort out a similiar problem with a similar token. Force a restar for the core every n hours has an impact on everything every n hours.

I would also be interested in a restart-free refresh of the token. Has anyone found a way?

No idea if it would work… Skip the secrets part and do it as entity that can be updated without the restart…

Dev tools
Services: homeassistant.update_entity

Or cmdline sensor that can be updated without a restart.

Not sure if a single secret could be updated with update entity…

I basically have this same problem.
I have a refresh token that doesn’t expire, and using that I get a JWT that’s valid for 12 hours. That JWT goes in a header in the rest sensor that gets the data.
I’ve made a script that updates the JWT and stores it in the secrets, but now I just realized that the value doesn’t get re-read by the rest sensor until Home-Assistant restarts… And I don’t want to restart every 12 hours, because of course that would always occur exactly when my wife’s doing something with it and then I’ll get the whole “I told you this smart home crap will never work” lecture :smiley:

So anyway… The way that seems the best would be to create another Rest sensor for the token value. But I haven’t managed to get that to work - the documentation says the headers should accept templates, and that could be used to get the value, but it just doesn’t seem to work… Also it’s a pain in the ass to debug because HASS needs to be restarted for the changes to take effect. I guess I’ll have to look into this again now that I’m a bit more familiar with templates.

Does anyone have a nice solution to this yet, Can’t we have a RESTful sensor which natively supports OAuth?

Hey everyone,

I had a similar issue and explained the resolution process here