JSON Web Tokens (JWTs)

JSON Web Tokens (JWTs) is an alternative authentication method to basic authentication supported by the API.

JWTs are an industry standard authentication method. A great introduction to the technology is available here, and a broad set of supported JWT libraries for a variety of languages and platforms are available.

A JWT is composed of a header, a payload, and a signature. The payload contains information called claims which describe the subject to whom the token was issued.

When to use JWTs?

Typically, basic authentication is the preferred method to authenticate requests to the API. However, JWTs are useful in certain cases.

Time-based expiration of credentials

If you desire to generate credentials that expire after a certain amount of time, using JWTs is a good way to achieve this.

The exp (expiration time) property of a JWT payload is honoured by the Sunshine Conversations API. A request made with a JWT which has an exp that is in the past will be rejected.

Keep in mind that using JWTs with exp means that you will need to implement regeneration of JWTs, which demands additional logic in your software.

Example use-cases:

  • Temporarily sharing credentials for debugging purposes.
  • Requiring integrations to rotate credentials by renewing them.

Sample JWT Structure with expiry

Header

{
    "alg": "HS256",
    "typ": "JWT",
    "kid": "<app-key-id>"
}

Payload

{
    "scope": "app",
    "exp": 1542499200 // unix timestamp representating 2018-11-18T00:00:00+00:00
}

Authenticating Users in SDKs

JWTs are required to identify your users by a custom identifier (userId) in SDKs. In this case, JWTs are signed with an app API key with a scope of appUser, and an additional payload property userId.

Signing a JWT

Step 1 Obtain an API key

To make requests with an app, which is the typical use-case, see Creating an App API Key.

Otherwise, read our account provisioning guide for how to generate an API key.

Step 2 Use the library available for your platform to create the JWT

We’ve included code samples for a few popular programming languages below. You can find libraries for more platforms here.

NodeJS:

Using the jsonwebtoken NPM module:

var jwt = require('jsonwebtoken');
var token = jwt.sign({ scope: 'app' }, SECRET, { header: { kid: KEY_ID } });

Ruby:

Using the ruby-jwt gem:

require 'jwt'

payload = {:scope => 'app'}
jwtHeader = {:kid => KEY_ID}

token = JWT.encode payload, SECRET, 'HS256', jwtHeader

Python:

Using the pyjwt module:

import jwt
token = jwt.encode({'scope': 'app'}, SECRET, algorithm='HS256', headers={'kid': KEY_ID})

Step 3 Start using the Sunshine Conversations API

# Calling GET /v1.1/appusers using a jwt
curl https://api.smooch.io/v2/apps/5963c0d619a30a2e00de36b8/users/c7f6e6d6c3a637261bd9656f \
     -H 'authorization: Bearer your-jwt'

Specifying the Scope of Access

The scope of access represents the authorization level of requests made with a specific JWT. The scope is specified in the payload when signing a JWT.

app

This is the most common case. Use the scope app with an app API key.

Header

{
    "alg": "HS256",
    "typ": "JWT",
    "kid": "<app-key-id>"
}

Payload

{
    "scope": "app"
}

appUser

Note also that the API key used to sign the JWT must be from an app. JWT with this scope are used when authenticating users.

Header

{
    "alg": "HS256",
    "typ": "JWT",
    "kid": "<app-key-id>"
}

Payload

{
    "scope": "appUser",
    "userId": "<user id>"
}

account

Used in account provisioning use cases.

Use an API key associated with a user account or a service account and specify a scope of account in the body of the JWT.

Header

{
    "alg": "HS256",
    "typ": "JWT",
    "kid": "<account-key-id>"
}

Payload

{
    "scope": "account"
}