Oauth Flow Cloud and Local


#1

I haven't see much documentation on gaining an access token without using createAccessToken manually in an application, so I did some researching and poking around into the local and cloud endpoints using the ifttt integration urls, and subbing in some of the urls and variables seen on ST.

The flows below are a replacement for the Smartthing's oauth flow

Enabling oauth in your application.
This one is probably known to most everyone, but including here just for completeness. In the app code section, create or click an existing app and click the Oauth and enable button. Make note of the client id and secret for later in the flow:

Local

Authorization code
Build the url with the following parameters

http://local-hub-ip/oauth/authorize?client_id=c072f41d-3eab-411d-b346-cbae989faa40&redirect_uri=http://localhost&response_type=code&scope=app

client_id=client id of your app
redirect_uri=server url that will accept the code. In this case I'm using localhost so I can just grab the code when it returns.
scope=app
response_type=code

The next screen will give you the option to either grant or deny the request and to set any devices you wish to give the app access to. You must have at least one preference in here to keep it from erroring out.

Once you click authorize you will be given the code in the url. Keep note of this.

image

Access Token
Take the code you received above and build a new link like below:

http://local-hub-ip/oauth/token?grant_type=authorization_code&client_id=c072f41d-3eab-411d-b346-cbae989faa40&client_secret=9650f975-d792-46c7-a9e4-15902699f45e&code=pbzFZC&scope=app&redirect_uri=http://localhost

grant_type=authorization_code
client_id=client id of your app
client_secret=client secret of your app 
code=code from the first call
redirect_uri=**Must be the redirect_uri from the first call**
scope=app

The redirect uri must be the same you put in the first call or this will not work

This must be sent as a POST call using a tool like POSTMAN or curl.

The response will be an access token in json format.

Cloud

Authorization Code
The same steps apply from above except now you use the Hubitat cloud url from below:

https://oauth.cloud.hubitat.com/oauth/authorize?client_id=c072f41d-3eab-411d-b346-cbae989faa40&redirect_uri=http://localhost&response_type=code&scope=app

You will be asked to sign in:

And then asked to choose a hub:

And then to configure:

And given a code:
image

Access Token
Build your POST url for Postman or Curl:

https://oauth.cloud.hubitat.com/oauth/token?grant_type=authorization_code&client_id=c072f41d-3eab-411d-b346-cbae989faa40&client_secret=9650f975-d792-46c7-a9e4-15902699f45e&code=nHbcIP&scope=app&redirect_uri=http://localhost

The redirect uri must be the same you put in the first call or this will not work

You now have a valid oauth token which can be used to access your app mappings :grin:

See @chuck.schwer's post below on getting the app endpoints from the cloud.

As of right now, these tokens must be passed using an "Authorization: Bearer :token:" header and not using an access_token=:token: according to @chuck.schwer's post below

Retrieving Endpoints

You can retrieve endpoints using the following url structures below:

Cloud:
https://oauth.cloud.hubitat.com/apps/api/endpoints

Local:
http://hub-ip/apps/api/endpoints

You must pass the token using an authorization header in the call:

Authorization: Bearer token


Instanceof org.codehaus.groovy.grails.web.json.JSONObject Equivalent
#2

There is one more endpoint that comes in handy. that is /apps/api/endpoints you can send a request to that endpoint with your bearer token and it will tell you the endpoint to use to call the app :


#3

Also, for the call to /oauth/token, "hubUID" param does not need to be passed. it is not used in that particular endpoint.


#4

Thanks! I've updated the post. I had that param come back from my ifttt flow inspection, but it might have been an artifact of my hub selection.


#5

@chuck.schwer I just noticed that if you already created an accessToken using createAccessToken in the app, the new auth tokens generated with this method do not work and return an <error>invalid_token</error> oauth error. Can this be changed so that the new tokens allow access to the app?


#6

i swapped multiple notes with a member of the staff to gather this info in parts, so it is awesome that you summarized it so beautifully here. Thanks so much.


#7

We currently treat access tokens and bearer tokens differently. We did have a discussion about treating bearer tokens the same as access tokens but it has not been implemented. So currently you have to pass access tokens in the url as a parameter and a bearer token in the headers as an Authorization header.

You can use both of them for the same app but the way to create them is different.


#8

Is there a way to get the endpoint of the app using the local oauth service on the hub? Mostly just for the app id since you have to know the ip of the hub to start with.


#9

it is the same, /apps/api/endpoints
ie:

http://<hub ip>/apps/api/endpoints

and pass the Bearer token in the Authorization header


#10

Thanks! I tried it before posting but just realized I misspelled something in the url. I'll add it to the post.


#11

The local OAUTH flow version stopped working for me after I updated my hub to 2.0. Anyone else having this issue?


#12

I never tried it prior to 2.0, but it's currently not working for me either. After getting the token and executing:

curl http://192.168.0.55/apps/api/endpoints -H "Authorization: Bearer <token>"

The response is simply: []


#13

In case anyone stumbles upon this old thread, this problem has been fixed some time ago.