Authentication using JWT

Overview

🚧

Please Note: Token to be used in Business SDK

The token used in the Business SDK will be JWT based token as described below.

The admin will be able to generate the API key and secret. These are created in the Card91 system and have the following properties

API key - A key that uniquely identifies an API Admin
API secret - A secret key for this API Admin that is used to create signed requests. As the name suggests, this value is supposed to be secret

A business could generate admins at will from their Business Dashboard.

SDK requests require HTTP Authentication using Bearer Tokens. The bearer token is a short lived token which needs to be generated by the caller.

We recommend generating the bearer token on every request. This should be done on the server side, to safeguard your secret.

How to generate the bearer token

The bearer token is a JWT token. The API key and Secret are needed to generate bearer tokens. The key and secret can be used indefinitely, till they are explicitly revoked.

Tip: You can try generating tokens manually at https://jwt.io/. Here is a sample

JWT Values Explained:

JWT HEADER: ALGORITHM & TOKEN TYPE

{  
    "alg": "HS512"  
}

JWT PAYLOAD: DATA

{  
    "sub": "Rrmzh31AhXWyJSEgF63Z7Xav1SpnVyIr43moTtZHIS4=", // API key  
    "iat": "1638944075", // current time in seconds (since EPOCH)  
    "exp": "1638944375" // token expiration time in seconds (since EPOCH)  
}

JWT verification is done using apiSecret

The HMAC SHA512 algorithm takes a message (made of header & data provided above) and a secret

function base64url(source) {
  // Encode in classical base64
  encodedSource = CryptoJS.enc.Base64.stringify(source);
  // Remove padding equal characters
  encodedSource = encodedSource.replace(/=+$/, '');
  // Replace characters according to base64url specifications
  encodedSource = encodedSource.replace(/\+/g, '-');
  encodedSource = encodedSource.replace(/\//g, '_');
  return encodedSource;
}
const apiKey = <<api_key>>;
const apiSecret = <<api_secret>>;
const tokenHeader = {
  "alg": "HS512",
};
const stringifiedHeader = CryptoJS.enc.Utf8.parse(JSON.stringify(tokenHeader));
const encodedHeader = base64url(stringifiedHeader);
const tokenData = {
  "sub": apiKey,
  "iat": Math.round(Date.now()/1000),
  "exp": Math.round(Date.now()/1000+5*60)
}
const stringifiedData = CryptoJS.enc.Utf8.parse(JSON.stringify(tokenData));
const encodedData = base64url(stringifiedData);
const authToken = encodedHeader + "." + encodedData;
let signature = CryptoJS.HmacSHA512(authToken, apiSecret);
signature = base64url(signature);
const signedToken = authToken + "." + signature;
jwtToken = signedToken;

The above jwtToken created in last step is used for Authentication & Authorization at Card91.

Please note that apiSecret is NOT base64 encoded.

The above script is pre-configured in our Postman Script. Just set api_key & api_secret as environment variables to make these calls.

Summary on the bearer token:

  • The algorithm used should always be HS512
  • Payload data contains the following keys:
    sub - should be the “API Key”
    iat - This is the current time (since EPOCH), in seconds
    exp - This is the expiry time (since EPOCH), in seconds. This cannot be more than 10 minutes from the current time. We recommend keeping it at 2-5 minutes from the current time value
  • Verify Signature
  • The header and payload is signed with the “API Secret” that is given to the business.

Sample JWT Value

eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJScm16aDMxQWhYV3lKU0VnRjYzWjdYYXYxU3BuVnlJcjQzbW9UdFpISVM0PSIsImlhdCI6MTYzODk0NDA3NSwiZXhwIjoxNjM4OTQ0Mzc1fQ.6B7gPxTUMfs9bHqbuX4AuKdp5AuvwVjkQDA8LzRlUWZXf4KhxDFvAw0TU1FoEws5eBRbAxQzwGqskwZvDkRpNA