[OH3] HowTo perform sendHttpGetRequest and sendHttpPutRequest in order to read/write through REST API

I’m trying to read and write a value from a channel configuration (via REST).

In OH2 it worked like:

val systemstatus_thing =sendHttpGetRequest('http://127.0.0.1:8080/rest/things/systeminfo%3Acomputer%3Aopuspi3')
    sendHttpPutRequest('http://127.0.0.1:8080/rest/things/systeminfo%3Acomputer%3Aopuspi3','application/json',systemstatus_thing.replaceAll('"pid":([0-9]+)','"pid":' + openHAB_PID))

Now, I’m getting:
[ERROR] [enhab.core.model.script.actions.HTTP] - Fatal transport error: java.util.concurrent.ExecutionException: org.eclipse.jetty.client.HttpResponseException: HTTP protocol violation: Authentication challenge without WWW-Authenticate header

OH3 API (at lease latest snapshots) requires wither Basic Authentication, if enabled, or an API Token.I do not recall when Basic Auth was introduced. I am testing HABApp with an API Token.

A Token can be created from your Admin page. More information here.

Getting a token is not the problem, however how to use it in the HTTP requests.
I wasn’t able to find any information about changed syntax (not even for the moved time setting) in any documentaion (especially on the next.openhab… site).

I know @Spaceman_Spiff has the token working in HABApp. Perhaps he can help clarify.

1 Like

If you use a basic auth you can just pass it in the url

http://user:password@127.0.0.1:8080/rest/things/systeminfo%3Acomputer%3Aopuspi3
1 Like

I was hoping it would at least be in a header. That is not even secured if you use https.

The header will automatically be created from the information from the url.
It’s built in.

The token is in plain text in the URL though, like http get options. That is why forms use post.

1 Like

I tried it with replacing user and password with my credentials, but failed with Unauthorized API request: Invalid Basic authentication credentials.
Should I use something like user=myUserName?

you have to enable basic auth first since it’s disabled by default

Edit:
Also I recommend creating a new user for every device.

1 Like

Ups!
Switched it on and tried again. Now it’s a

Fatal transport error: java.util.concurrent.TimeoutException: Total timeout 5000 ms elapsed

BTW : A new used for each device? I’m trying to get data to and from the REST API, so it is the device which runs openHAB which tries to get something from itself.

It is a service on the device ( & executed by a user) trying to get information from the openHAB service, outside of openHAB. The fact it is running on the same device does not matter to OH.

Using the commands like:

val systemstatus_thing =sendHttpGetRequest("http://opus:******@127.0.0.1:8080/rest/things/systeminfo%3Acomputer%3Aopuspi", 10000)
        val returnvalue = sendHttpPutRequest("http://opus:*****@127.0.0.1:8080/rest/things/systeminfo%3Acomputer%3Aopuspi","application/json",systemstatus_thing.replaceAll('"pid":([0-9]+)','"pid":' + openHAB_PID), 15000)

Can’t say if it would work with smaller timeouts. My testing-system got a bit unresponsive yesterday, that caused the problems. Now it is working, THANKS!

1 Like

Hello,

i have a related problem with an thing i want to disable / enable per rule.

The url i got from API explorer, basic auth is enabled and added to url

var String url = "restuser:restpass@https://openhab.srv.local/rest/things/onkyo%3ATX-NR636%3A18b0a1bd-65a1-bdb9-70a8-bd0965b96cd5/enable"
var put = sendHttpPutRequest(url, "application/json", 'enabled', 5000)

failed: Invalid URI host: null (authority: null)

this is the original thing id
onkyo:TX-NR636:18b0a1bd-65a1-bdb9-70a8-bd0965b96cd5

what i am missing here?

It’s like this:

var String url =" https://restuser:restpass@openhab.srv.local/rest/things/onkyo%3ATX-NR636%3A18b0a1bd-65a1-bdb9-70a8-bd0965b96cd5/enable"

Oh no :disappointed:, i should get more sleep, thank you.

Hi All,

how to use sendHttpGetRequest with a API token instead of Basic Auth?

I’m struggling from a while, trying almost all possible options … unlucky.

Any clue?

thanks
Andrea

Did you have a look to this thread [JavaScript] Syntax to insert API Token into SendHTTPGetRequest - #4 by alexxio

1 Like

I’ve seen that topic, but not sure how to change my rule

sendHttpPutRequest("http://user:password@127.0.0.1:8080/rest/things/openuv:uvreport:local:home/enable", "application/json", 'true')

Questions:

  1. the user created via Karaf is common user (not admin) … is the normal user able to send a Put Request? to me, it sounds like a “write” permission, and it should be an admin characteristic

  2. how to modify the user:pass structure with the API token?

btw if I need an admin user to send put requests, also the API token should be generated by an admin account right?

thanks
Andrea

found and tested the solution :slight_smile:

val headers = newHashMap("Authorization" -> "Bearer <put_your_token_here>", "WWW-Authenticate"-> "Basic")
sendHttpPutRequest("http://127.0.0.1:8080/rest/things/openuv:uvreport:local/enable", "application/json", 'false', headers, 1000)

thanks @Wolfgang_S for the input :slight_smile:

Andrea

5 Likes