To verify that data sent from your Front Connector is legitimate, validate the signature before accepting it into your system.

The requests made to your server will include 2 headers: X-Front-Signature and X-Front-Request-Timestamp. First, check that the timestamp says the request was made recently in order to prevent replay attacks. We recommend 5 minutes as the maximum time before rejecting a message.

  1. Retrieve the X-Front-Request-Timestamp header on the HTTP request and the body of the request.
  2. Concatenate the timestamp and the JSON stringified body of the request to form a string. Use a colon as the delimiter between the two elements.

    📘

    GET and DELETE requests return a string with the value "undefined" as the body

  3. Using HMAC SHA256, hash the above string, using your Channel Type Secret Key as the key.

This should match the X-Front-Signature header. If it does not, you should not trust this message. See the following TypeScript example for how to validate a message and generate a token.


Sample application

The Auth file of our Basic application object handler sample application demonstrates verifying that a request is coming from Front.

/**    
 * Validate that the request is from Front
 * 
 * Concatenate the request body + timestamp, delimited with a colon.
 * Take SHA256 HMAC and validate it's equal to the X-Front-Signature
 * In the Request Header
 * 
 * In production, we recommend loading Channel Type secret from a configuration file.
 * 
 * @param {Request} req: Incoming request from Front.
 * @param {string} channelTypeSecret: Secret Key of your Channel Type. Was given to you when your Channel Type was created.
 * @returns {boolean} Boolean denoting whether or not request is from Front.
 */
function isRequestFromFront(req: Request, channelTypeSecret: string): boolean {
  const timestamp = req.headers['x-front-request-timestamp'];
  const rawBody = JSON.stringify(req.body);
  // GET and DELETE requests send a string with the value "undefined" as the body
  const baseString = `${timestamp}:${rawBody}`;
 
  const hmac = crypto.createHmac('sha256', channelTypeSecret)
    .update(baseString)
    .digest('base64');
 
  return hmac === req.headers['x-front-signature'];
}


/**
 * Creates a JSON web token
 * 
 * jwt is your preferred JWT library found at https://jwt.io/
 * In production, we recommend loading Channel Type ID and secret from a configuration file.
 *
 * @param {string} channelTypeId: ID of your Channel Type. Was given to you when your Channel Type was created.
 * @param {string} channelTypeSecret: Secret Key of your Channel Type. Was given to you when your Channel Type was created.
 * @param {number} channelId: Incoming request from Front.
 * @returns {string} Signed JSON web token
 */
function buildToken(channelTypeId: string, channelTypeSecret: string, channelId: number) {
  // Mark token to expire within 5 seconds for security (small usage window)
  const exp = Math.floor(new Date().valueOf() / 1000) + 5;

  // Can be any string, can be used by your system to identify tokens
  const jsonWebTokenId = 'abc123';
  
  const payload = {
    iss: channelTypeId,
    jti: jsonWebTokenId,
    sub: channelId,
    exp
  };

  return jwt.sign(payload, channelTypeSecret);
}