Installed App ID - OAuth

Hi all,

I am implmenting an OAuth flow for allowing users to access the Smarthings Api through my application. I have functionality to get the OAuth access token from the users but I am just curious on what the installed _app_id is? In the developer documentation (you might not be able to access this unless you are registered for OAuth) for the return when retrieving the Access Token using the Access Code the sample given says the information below is what should be returned:

{
  “access_token”: “a605e9d7-46a9-d867-955c-74063dooc4e9”,
  “token_type”: “bearer”,
  “refresh_token”: “5d8rr9d7-a988-0a45-955c-74068fh8ur0l”,
  “expires_in”: 299,
  “scope”: “x:devices:* r:devices:*”
}

However in reality I am getting what is shown below (replaced my tokens with ‘*’)

{
  access_token: '*******************',
  token_type: 'bearer',
  refresh_token: '*********************',
  expires_in: 75549,
  scope: 'r:locations:* x:devices:* r:devices:*',
  access_tier: 0,
  installed_app_id: '***********************'
}

Is the installed_app_id unique to the user? If a user logs into my app, signs out and then a week later signs back in will the installed_app_id be the same? Would be a handy way to identify which user is which and then just update the Tokens as needed. It seems to be how the context store is using it as well as the primary key in a user database but I just want to make sure.

Hello Warren,

Taking into account that you refer to this sample, here is the feedback:

  • The response includes the installedAppId because you are also creating a SmartApp.
  • The installedAppId is a unique identifier, so each instance has a new ID, this means that if the same user authorizes the access to your application in different locations, the installedAppId will be different for each location as well.
  • The sample has the instruction to delete the current installedApp when users click on logout (this will generate a new installedAppId every login), if you omit this command, then every time the user completes the authorization, you will receive the same installedAppId per location.
  • About the Token refresh, the request needs the parameters defined in this document.
    It will return the new AccessToken next to the InstalledAppId where it belongs.
  • Using the InstalledAppId you will be able to update the token in Dynamo once you make the refresh, but it doesn’t identify users, only application instances.

If this answers your question, can you please mark it as solved? If not, let me know what’s going on and I can dig in further.

1 Like

Hi @nayelyz,

I had a look at the sample but just to be clear I am not using the smart app SDK at the moment that they use, I am just using axios to make calls to get the Access Token and Refresh Token, does this still mean I am creating a smart app or am I just using the API? Is there a difference? The snippet below is the part of my code which obtains the access token, its just a request to the API.

// code is the Access code for OAuth
const verifyAccessToken = async function (code){
    // The data to be sent 
    var data = qs.stringify({
        'grant_type': 'authorization_code',
        'code': code,
        'client_id': process.env.CLIENT_ID,
        'redirect_uri': `${process.env.URL}/oauth/callback`  
    });
    // The configuration of the POST
    var config = {
        method: 'POST',
        url: 'https://api.smartthings.com/v1/oauth/token',
        headers: { 
            'Content-Type': 'application/x-www-form-urlencoded'
        },
        auth:{
            username: process.env.CLIENT_ID,
            password: process.env.CLIENT_SECRET
        },
        data : data
    };
    // Try send the request 
    try {
        const res = await axios(config);
        await user_db.logUserInfo(res.data) // log this to a database 
    }catch(error){
        console.log(error)
    }  
}

I think you have answered my question on the installed app ID but just to be clear if a user logs into my app, chooses the location home and I get the refresh token, access token, installed app ID etc and I dont implement the logout functionality as in your sample. If the same user logs in 1 year later, sets the location to home I will get the same installed_app_id as the first log in?

You mention the refresh token, just a question on that. The documentation says that the access token lasts for 24 hours and the refresh token lasts for 30 days. If I am continuously using the access token on behalf of the user in the background do I have to generate a new Access Token and Refresh Token every 24hrs as in the document you linked or is there a way just to generate a new access token and then generate a refresh token every two weeks?

Is there a way to get users information through the API once I have there Access Token? Even a users name or a unique user ID?

Hi @Warren1,

Since you are only making the request to get the OAuth token, this is the installedAppId provided by OAuth linked to the granted token so users can create other elements, such as Subscriptions that must belong to an Installed Application so they don’t have to request an extra token for this purpose.
About the user login after 1 year, the installedAppID has no expiration time, but if it is removed through the SmartThings API or the “Linked services” option in the mobile app, the next login will generate a new InstalledAppID will be assigned.
If you are constantly updating the Access Token, the refreshToken is refreshed as well, if you don’t, the refreshToken has an expiration time of 30 days, but it is recommended to refresh it every 15 days to not lose it, but the expiration of the AccessToken (24 hours) won’t change.
About the user information, due to the privacy policy, you won’t have access to it, would you mind sharing the information you would need and the purpose of it?

It would just be to uniquely identify the user and then when pulling data from users sensors in there home I could set up a relation from within a database. Just something that wont change even if the user attempts to install the app in another location as that would change the Installed app ID.

Hi @Warren1,

The points below can help you out to relate the information:

  • In one user’s account, there might be different locations and each device belongs to only one of them.
  • An OAuth integration can be installed in different accounts and different locations, to identify each instance the InstalledAppId is used and only the Access Token linked to this can interact with it. So, using these two values, your integration should be able to know the user account and the location where it belongs, this won’t change no matter how many instances it has installed.

You can go through the different endpoints to see which information could you get from them.

Hi @nayelyz,

I am trying to verify that the given user is allowed to use my service based upon information I obtain from them through the REST API once they have granted me access to get there access token. I need a piece of information that is constant through out that could verify that this user is registered to my service.

I know that if I disconnect a device and reconnect it the device ID changes as it has happened to me before. Do location ID’s ever change or is there anything that would cause them to change?

Is there anyway I could possibly get a MAC address or ID on the Hub that never changes like the even if the hub is disconnected and factory reset?

@Warren1

When you make a call to the following endpoint, you get ownerId and locationId. Both of these tokens are good to identify the client.

https://api.smartthings.com/v1/installedapps/{installedAppId}

This API however, is not ready for production. It will be quiet some time before you will be able to use in your application.

Hi @625alex,

Thanks for the reply, I have made a request to the endpoint and see the information you mentioned returned, can I ask why I shouldn’t use this in my development? Is it still being worked on and could possibly change?

Hi @nayelyz,

I know this is an old question but just had a taught on this.

I am storing installed App Id’s within a database and you mention I can create subscriptions using this. Would this be using the SmartThings SDK id have to make subscriptions with?

For example if I wanted to make a bulk query to my database, get all the installed app ID’s and then set up subscriptions for certain devices, does the SDK allow me to this with the Installed App ID?

const smartapp = new SmartApp()
  .updated(async (context, updateData) => {
          await context.api.subscriptions.delete() // clear any existing configuration
          await context.api.subscriptions.subscribeToDevices(context.config.contactSensor, 
  'contactSensor', 'contact', 'myDeviceEventHandler');
      })
      .subscribedEventHandler('myDeviceEventHandler', async (context, event) => {
          const value = event.value === 'open' ? 'on' : 'off';
          await context.api.devices.sendCommands(context.config.lights, 'switch', value);
      });

Something like the block of code above but dynamically passing in Installed App ID’s so I can link back to a given user.

EDIT
Upon reading the docs it does seem to be possible I think as there is a input appId to the SmartApp constructor, is this the same as the installedAppId?

You could make a request to the InstalledApps endpoint to create the subscription. Then, use the SmartApp SDK to receive the events.
In my sample, I created a capability subscription and the events are received in switchHandler. In the event and context parameter, you can see the origin and value of the event (device, locationId, installedAppId, etc.)

Hi @nayelyz,

Thanks for the reply

I cant seem to access the link to view this sample, could you point me in the direction of the url or code for it?
Or is it the original sample here you are referring to?

Sorry, here it is again, I fixed the link above too.

1 Like

Hi @nayelyz,

Thanks for the response, I’ll give it a go. I actually started trying to convert some of it to using SDK fully and ran into a bit of a problem. I created it on a separate thread though here to avoid this getting cluttered. If you had any ideas on it would be of help!