Authentication

OAuth

Bootic API requests are authenticated using OAuth2 access tokens.

GET /v1/products.json HTTP/1.1
Host: api.bootic.net
Authorization: Bearer YOUR-ACCESS-TOKEN-HERE
Content-Type: application/json
Accept: application/json

OAuth2 is a protocol that lets external apps request authorization to private details in a user’s Bootic account without getting their password. This is preferred over Basic Authentication because tokens can be limited to specific types of data, and can be revoked by users at any time.

All developers need to register their application before getting started. A registered OAuth application is assigned a unique Client ID and Client Secret. The Client Secret should not be shared.

This is a low-level description of the protocol and the different authentication flows. It is recommended that you use one of the libraries available for different languages rather than implementing your own.

Supported OAuth2 flows

  1. Authorization Code Grant for online applications and single sign-on.
  2. Implicit Grant for JavaScript and client-side apps.
  3. Client Credentials Grant for server-side scripts.
  4. Resource Owner Password Credentials Grant for trusted apps.
  5. JWT Bearer Authorization Grant for refreshing expired tokens.

Authorization Code Grant

Spec: http://tools.ietf.org/html/rfc6749#section-4.1

User signs-on and obtains an access token. Used by third-party apps acting on behalf of a logged-on user or that want to use Bootic as an identity provider. This flow will be familiar if you’ve used Facebook, Twitter or Google authentication before.

+----------+
|          |
|   User   |
|          |
+----------+
     ^
     |
    (B)
+----|-----+          Client Identifier      +---------------+
|         -+----(A)-- & Redirection URI ---->|               |
|          |                                 |               |
| Browser -+----(B)-- User authenticates --->|auth.bootic.net|
|          |                                 |               |
|         -+----(C)-- Authorization Code ---<|               |
+-|----|---+                                 +---------------+
  |    |                                         ^      v
 (A)  (C)                                        |      |
  |    |                                         |      |
  ^    v                                         |      |
+---------+                                      |      |
|         |>---(D)-- Authorization Code ---------'      |
|  App or |          & Redirection URI                  |
| website |                                             |
|         |<---(E)----- Access Token -------------------'
+---------+

Implicit Grant

Spec: http://tools.ietf.org/html/rfc6749#section-4.2

This flow is optimized for JavaScript-only and other client-side apps that can’t store secret credentials securely.

The user will be redirected to login at Bootic’s authentication service, and then redirect back to your site with an access token in the URL’s fragment (#access_token=xxx).

+----------+
|          |
|   User   |
|          |
+----------+
     ^
     |
    (B)
+----|-----+          Client Identifier     +---------------+
|         -+----(A)-- & Redirection URI --->|               |
|          |                                |               |
| Browser -|----(B)-- User authenticates -->|auth.bootic.net|
|          |                                |               |
|          |                                |               |
|          |<---(C)--- Redirection URI ----<|               |
|          |          with Access Token     +---------------+
|          |            in Fragment
|     (F)  |
|          |
+-|--------+
  |    |
 (A)  (G) Access Token
  |    |
  ^    v
+---------+
|         |
|  Client |
|         |
+---------+

Client Credentials Grant

Spec: http://tools.ietf.org/html/rfc6749#section-4.4

Use this flow for automated scripts or applications that need to query the API directly and not on behalf of a particular user.

Examples are backup or sync scripts, cron jobs or command-line utilities.

+---------+                                  +-----------------+
|         |                                  |                 |
|         |>--(A)- Client Authentication --->|                 |
| Client  |                                  | auth.bootic.net |
|         |<--(B)---- Access Token ---------<|                 |
|         |                                  |                 |
+---------+                                  +-----------------+

Request

You must make a POST request to https://auth.bootic.net/oauth/token. The application’s client_id and client_secret pair must be used as Basic Authentication in the Authorization header.

The request must include the following parameters:

Parameter Value
grant_type (required) client_credentials
scope (optional) ‘admin’, ‘public’, etc.
POST /oauth/token HTTP/1.1
Host: auth.bootic.net
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials
curl -XPOST -u "client_id:client_secret" -d "grant_type=client_credentials&scope=admin" https://auth.bootic.net/oauth/token
require 'oauth2'

client = OAuth2::Client.new(
  ENV['BOOTIC_CLIENT_ID'],
  ENV['BOOTIC_CLIENT_SECRET'],
  site: "https://auth.bootic.net"
)

access_token = client.client_credentials.get_token({}, 'auth_scheme' => 'basic')

puts access_token.token

Response

Status: 200 OK
Content-Type: application/json; charset=utf-8
Connection: keep-alive
Cache-Control: must-revalidate, private, max-age=0
Date: Wed, 31 Jul 2013 21:11:52 GMT
{
  "access_token": "kdbedeude53535edvehdbe.deideudebdede.deidyw336dede",
  "token_type": "Bearer",
  "expires_in": 3600,
  "scopes": "public,admin"
}

Resource Owner Password Credentials Grant

Spec: http://tools.ietf.org/html/rfc6749#section-4.3

+----------+
|          |
|   User   |
|          |
+----------+
     v
     |    Resource Owner
    (A) Password Credentials
     |
     v
+---------+                                  +---------------+
|         |>--(B)---- Resource Owner ------->|               |
|         |         Password Credentials     |               |
| Client  |                                  |auth.bootic.net|
|         |<--(C)---- Access Token ---------<|               |
|         |                                  |               |
+---------+                                  +---------------+

This flow is only suitable for trusted apps and scripts, as it requires that the user submits their Bootic login and password.

Request

You must make a POST request to https://auth.bootic.net/oauth/token. The application’s client_id and client_secret pair must be used as Basic Authentication in the Authorization header.

The request must include the following parameters:

Parameter Value
grant_type (required) password
scope (optional) ‘admin’, ‘public’, etc.
username (required) ‘johndoe’, etc.
password (required) ‘password123’, etc.
POST /oauth/token HTTP/1.1
Host: auth.bootic.net
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded

grant_type=password&username=johndoe&password=password123
curl -XPOST -u "client_id:client_secret" -d "grant_type=password&scope=admin&username=johndoe&password=password123" https://auth.bootic.net/oauth/token
require 'oauth2'

client = OAuth2::Client.new(
  ENV['BOOTIC_CLIENT_ID'],
  ENV['BOOTIC_CLIENT_SECRET'],
  site: "https://auth.bootic.net"
)

access_token = client.password.get_token('johndoe', 'password123', auth_scheme: 'basic')

puts access_token.token

Response

Status: 200 OK
Content-Type: application/json; charset=utf-8
Connection: keep-alive
Cache-Control: must-revalidate, private, max-age=0
Date: Wed, 31 Jul 2013 21:11:52 GMT
{
  "access_token": "kdbedeude53535edvehdbe.deideudebdede.deidyw336dede",
  "token_type": "Bearer",
  "expires_in": 3600,
  "scopes": "public,admin"
}

JWT Bearer Authorization Grant

Spec: http://tools.ietf.org/html/draft-ietf-oauth-jwt-bearer-08#section-4

This grant is used to exchange an expired access token for a new token with the same scopes. Use this to get tokens programatically on behalf of a user or to refresh expired user access tokens in the duration of your app’s user session.

This grant type requires that you encode the grant claims as a JSON Web Token string. Explaining the JWT Spec is out of the scope of this guide and we strongly recommend that you use a JWT library available for your language instead of rolling out your own.

This grant requires that a pre-exiting access token. Trying to use this grant to obtain unauthorized tokens will be rejected by the authentication service.

JWT Claims

The claims section of the JWT token has the following parameters:

Parameter Description Example
iss (required) application’s client_id 58842b2b218081e66b59c4901d262cda
aud (required) any string for now My App
exp (required) grant expiry date, in seconds since epoch 1397569414
sub or prn (required) An existing and expired access token eyJ0eXAiOiJKV1QiLCJhbGciOiJIUI...

The JWT token must be signed with the application’s client_secret.

Request

Parameter Value
grant_type (required) urn:ietf:params:oauth:grant-type:jwt-bearer
assertion (required) (encoded JWT token)
POST /oauth/token HTTP/1.1
Host: auth.bootic.net
Content-Type: application/x-www-form-urlencoded

grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion=JWT_TOKEN_HERE
curl -XPOST \
  -d "grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion=JWT_TOKEN_HERE" \
  https://auth.bootic.net/oauth/token
require 'oauth2'

# The expired token that you want to exchange for a new one
expired_token = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdXRoIjo5OCwiYXB...'

# Setup an OAuth2 client. Client ID and secret not required for here for this flow.
client = OAuth2::Client.new(nil, nil, site: "https://auth.bootic.net")

# The JWT grant must have an expiration date, in seconds since the epoch. For most cases a few seconds should be enough.
exp = Time.now.utc.to_i + 5

# Use the "assertion" flow to exchange the JWT grant for an access token
access_token = client.assertion.get_token(
  hmac_secret: ENV['BOOTIC_CLIENT_SECRET'],
  iss: ENV['BOOTIC_CLIENT_ID'],
  prn: expired_token,
  aud: 'test',
  exp: exp
)

puts access_token.token #=> "f9f5894a8a6530174c535486b7a56f13"

Response

Status: 200 OK
Content-Type: application/json; charset=utf-8
Connection: keep-alive
Cache-Control: must-revalidate, private, max-age=0
Date: Wed, 31 Jul 2013 21:11:52 GMT
{
  "access_token": "kdbedeude53535edvehdbe.deideudebdede.deidyw336dede",
  "token_type": "Bearer",
  "expires_in": 3600,
  "scopes": "public,admin"
}

Errors

Errors will be returned for invalid credentials, missing required parameters, unauthorized scopes and others.

Status: 400 Bad Request
Content-Type: application/json; charset=utf-8
Connection: keep-alive
Cache-Control: must-revalidate, private, max-age=0
Date: Wed, 31 Jul 2013 21:11:52 GMT
{
  "error": "invalid_grant",
  "error_description": "JWT token MUST have 'exp' claim"
}