Last updatedDec 8, 2017

Understanding JWT for apps

HipChat to add-on HTTP calls

Any request made by HipChat to your add-on configuration page will include a JSON Web Token (JWT), an encoded form of JSON data and a signature to verify its contents. It is recommended you use one of the existing JWT libraries to decode the token. You can use the JWT token to validate that:

  • The request comes from HipChat
  • The request comes from the right installation
  • The request was not altered in transit

The JWT token is included either:

  • in the HTTP header "Authorization"
  • in the request parameter: "signed_request"

JWT tokens are base64 encoded. Once decoded, the JWT token is made of 3 elements delimited by a "."

  • Header
  • Payload
  • Signature

The payload contains the following elements, which provide contextual information about the call:

Attribute
Description
issIssuer: OAuth Client ID
subSubject: User ID
iatIssued at timestamp
expExpiration timestamp
jtiJWT ID (random 20 chars)
context

Custom attributes:

user_tzUser timezone
room_idRoom ID

The token is signed. You can verify its signature using the sharedSecret sent during installation. 

Here are the steps to handle a JWT token:

  • Extract the token from the request. Depending on the call: 
    • from the HTTP header "Authorization"
    • from the request parameter: "signed_request"
  • Decode the base64-encoded token
  • Extract the oauthId which is in the 'iss' (issuer) parameter from the JWT token
  • Lookup the installation data received via the Installation flow for this oauthId
  • Use the sharedSecret from the installation data to validate the signature of the token 

For example, using Node.js:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var jwtUtil = require('jwt-simple')

//extract the token from the request
var encodedJwt = request.query['signed_request'];

//first decode the token without validating the signature
var jwt = jwtUtil.decode(encodedJwt, null, true);

//then lookup the installation details based on the oauth ID in the token
var oauthId = jwt['iss'];
var installation = installationStore.getInstallation(oauthId); 

//Then validate the token signature
jwtUtil.decode(encodedJwt, installation.oauthSecret);

Add-on front-end to add-on backend calls

The HipChat Javascript API includes a function so your add-on front-end can retrieve a JWT token to talk to your add-on back-end. 

This token has the same structure as the one used for HipChat to add-on calls. 

In particular, it contains the context of the call (oauth client ID, user ID, etc.). 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//Retrieve a JWT token
HipChat.auth.withToken (function(err, token) {
  if (err) {
    // error
  } else {
    //Include this token in a REST call to the add-on backend
    $.ajax({
         type: "POST",
         url: "/your-addon-endpoint",
         headers: { 'authorization': 'JWT ' + token },
         data: {
            //custom data
         }
    });
  }
}