Cloud to Cloud OAuth (Rest API)

The LIFX c2c example @hyeyoung linked-to is a good example to look at.

I’ll also try and provide some more info here about the OAuth flow here.

Basic steps

  1. Register your OAuth integration with the third-party. The requirements will vary depending on the third-party service. This typically requires registering an OAuth callback URL for the integration. The callback URL should be https://api.smartthings.com/oauth/authorize
  2. Use an OAUTH configuration setting input to prompt the user to authenticate and authorize with the third-party.
  3. Handle the OAUTH_CALLBACK lifecycle event to exchange the authorization code for a token.
  4. Store and use the token to make requests to the third-party.

OAUTH configuration setting

During app configuration, use the OAUTH setting type to allow the user to authenticate with the third-party and authorize the requested permissions. The urlTemplate is the OAuth URI the third-party requires, and will vary by provider.

An example for requesting authorization with GitHub is shown below, requesting authorization for user:email scope. This assumes that the OAuth app has been registered with GitHub, which will provide the Client ID and secret. Note that GitHub will look up the OAuth redirect URI to call with the authorization code based on the client ID (which should be registered as https://api.smartthings.com/oauth/callback), but your third-party may have different requirements, such as specifying the redirect URI as a query parameter to their authorize URL.

settings: [
	{
		id: "githubAuth",
		name: "Authenticate with GitHub",
		description: "Tap to set",
		type: "OAUTH",
		required: true,
		urlTemplate: "https://github.com/login/oauth/authorize?client_id=YOUR-CLIENT-ID&scope=user:email"
	}
]

When users press the input during installation, they will be directed to the third-party (GitHub in the example above), and once authenticated, will typically be asked to grant the specific access permissions being requested by the app. Once the user accepts, that will trigger the OAUTH_CALLBACK lifecycle to your app.

OAUTH CALLBACK lifecycle

Upon successful authentication and authorization, the third-party will call the URI you registered as the callback (again, should be https://api.smartthings.com/oauth/callback) with an authorization code. SmartThings will route this request to your SmartApp with an OAUTH_CALLBACK lifecycle event. Your app should then exchange the authorization code for a token.

The OAUTH_CALLBACK lifecycle includes a oauthCallbackData object on the request, which contains the following information: the ID of the installed app, as well as the query parameters from the OAuth callback (in the urlPath property). This is typically where the auth code can be found. For example, a response from GitHub may look like:

{
	"installedAppId": "234lkjlasd-234u8ufa-ii54u2304",
	"urlPath": "code=0p87asdfj2yn3jldf"
}

The app can then use the returned code to request a token. Continuing the GitHub example, it may look like (example shown in Node.js):

const rp = require("request-promise");
let code = oauthData.urlPath.split("code=")[1];
let opts = {
	url: "https://github.com/login/oauth/access_token",
	method: "POST",
	json: true,
	form: {
		client_id: YOUR-CLIENT-ID,
		client_secret: YOUR-CLIENT-SECRET,
		code: code
	}
};
rp(opts)
	.then(function(tokenResp) {
		let token = tokenResp.access_token;
		// store token associated with this installed app
    })
	.catch(function(err) {
		console.error(`Error getting token from code: ${err}`);
	});

At this point, your app can use the token to make requests to the third-party.