Authenticating users with OAuth 2.0

Introduction

The OAuth 2.0 protocol allows a user to grant you API access to their Xhale account without sharing their password with you.

The OAuth 2.0 'authorization code' flow is initated by sending the user to a URL on the Xhale site where they login and then grant permission for you to access their data via the API. Xhale then redirects them back to your site along with a grant token. You then perform (preferably) a server to server request, in order to exchange this grant token for a full access token. This access token is then used to authenticate future API requests.

Secure connections only

OAuth relies on TLS connections (HTTPS). Your implementation should not be considered secure without it.

Create an application

Setting up an application is currently handled manually by Xhale.

To set this up we will need a redirect URL which we will whitelist.

This is the URL that the user is sent back to after authenticating with Xhale and authorising your access to the API. Without this URL we won't complete the flow. We don't have a separate test site, so if you need a test account for development purposes please let us know and provide the URL for that as well.

Set up the authorization flow

Since OAuth 2.0 is a standard protocol, there is almost certainly a library that can be used to help implement this flow.

Redirect to Xhale

The user will initiate the authentication flow, probably by pressing a button on your site. When they do this, you will need to generate an authoriation URL and redirect the user to that page on the Xhale site. Here's an example redirect:

HTTP/1.1 302 Found

https://trainxhale.com/api/oauth/authorize/
  ?scope=read+write
  &state=gyFhPbrM1ALv
  &response_type=code
  &client_id=dTNqyr7EGzSBgUJxhf99o2QFUuEpxsz7rUmwvrEs

parameter description
response_type Must be 'code' which is currently the only method we support.
client_id The ID we will issue to you, which uniquely identifies your application.
scope Optional. Declare whether you want only 'read' access or 'read+write'. Read and write is the default. If you want to upload training data, you will also need to request the 'upload' scope. Users will be asked to grant you access to each of these scopes.
state A random string which is returned to you as a query parameter in the redirect. This can be used to ensure that when your redirect endpoint is hit, the request originated from you.

Authorisation

After you've redirected the user to the Xhale authorisation endpoint, they will then need to log in (if they are not already) and press a button to authorise access.

Back to you

We will then redirect back to your redirect URL that you whitelisted above.

https://example.com/oauth-complete
  ?code=SplxlOBeZQQYbYS6WxSbIA
  &state=af0ifjsldkj
      

Retrieve the state from the GET response and ensure it matches what you previously stored.

Get the code and use this to make a POST request to our token endpoint 'https://trainxhale.com/api/oauth/token/' with the following post data:

parameter description
code The 'code' you just grabbed.
grant_type the string 'authorization_code'
redirect_uri Your whitelisted URL

Authorise the request with Basic Auth using your Client ID as the username and Client Secret as the password. Here is an example request:

   
POST /api/oauth/token/ HTTP/1.1
Host: trainxhale.com
Content-Type: application/x-www-form-urlencoded
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW

code=SplxlOBeZQQYbYS6WxSbIA
&grant_type=authorization_code
&redirect_uri=https://example.com/oauth-complete
      

We will respond with an access token, expiry time and a refresh token (see below) which you should store securely as these will provide API access for this user.

That's the OAuth flow complete.

Refresh tokens

Access tokens have a limited lifetime. If you try to use the access token after it has expired you will receive a response with 401 status code error. You should therefore first check the expire time before making a request and if it has expired or is soon going to expire, first request a new access token. If you receive the 401 error it means it has probably expired already, so request a new access token and use it to repeat your request.

   
POST /api/oauth/token/ HTTP/1.1
Host: trainxhale.com
Content-Type: application/x-www-form-urlencoded
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW

refresh_token=SplxlOBeZQQYbYS6WxSbIA
&grant_type=refresh_token
      

Save the new access token and refresh token and then use the token as before.

Using the token to make API requests

You now use the access token to authorize API requests. To do so you present the token in a request as a Bearer authorisation header, for example: 'Authorization: Bearer db015b7280da9ebc7c0c4fc48a5d6a2f14780ecf'

Please see this page for details on the full API endpoints available to you along with examples.

Revoke tokens

If your user no longer wants to give you access to our API, you can make a request to revoke the token provided above.

Make a POST request to trainxhale.com/api/oauth/revoke-token/ with the following parameters:

parameter description
token Either the access token or refresh token
token_type_hint Either 'refresh_token' or 'access_token'. This is optional.
   
POST /api/oauth/revoke-token/ HTTP/1.1
Host: trainxhale.com 
Content-Type: application/x-www-form-urlencoded
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW

token=45ghiukldjahdnhzdauz
&token_type_hint=refresh_token
      

Dealing with errors

If the user presses the cancel button they will be sent to:

http://example.com/your-whitelisted-url?error=access_denied

If you receive a 401 error, this likely means your token has expired. Use your refresh token to request a new access token.