Verifying HTTP Signature (Webhook SmartApp, node.js)


(Eric Zeng) #1

Anyone else having trouble verifying the http signature in their app? I’m going off of the node.js examples in the docs but can’t seem to get this to work. I used the “publicKey” field in the response from SmartThings when I originally registered the smartapp.

Here’s the relevant snippets in my app.

const bodyParser = require('body-parser');
const express = require('express');
const httpSignature = require('http-signature');

// This loads the JSON file you get when you run the curl command to register a 
// webhook SmartApp.
const CONFIG = require('./auth/config.json');
const PUBLIC_KEY = CONFIG.app.webhookSmartApp.publicKey;

function signatureIsVerified(req) {
  try {
    let parsed = httpSignature.parseRequest(req);
    console.log(parsed);
    console.log(PUBLIC_KEY);
    if (!httpSignature.verifySignature(parsed, PUBLIC_KEY)) {
      console.log('forbidden - failed verifySignature');
      return false;
    }
  } catch (error) {
    console.error(error);
    return false;
  }
  return true;
}

app.post('/', (req, res) => {
  if (!req.body) {
    res.status(400);
    res.send('Invalid request');
    return;
  }
    if (req.body.lifecycle === 'PING') {
    handlePing(req, res);
    return;
  }

  if (!signatureIsVerified(req)) {
    res.status(403);
    res.send('Unauthorized');
    return;
  }
....
});

Every request for the CONFIGURATION lifecycle will just hit the line that says “forbidden - failed verifySignature”.


(Jim Anderson) #2

Couple things to check:

  1. If creating the app record via the API, make sure to replace all \r\n characters with actual line breaks.
  2. Make sure you restarted your server after changing the public key file, since the file is loaded on server startup.

One of those two things is almost always the culprit (outside of simply copy/pasting incorrectly).


(Eric Zeng) #3

In case anyone else reads this later on, it turns out this was not working because I was using the wrong public key. I had multiple SmartApps registered, and got confused about which SmartApp my server was actively running as. The signature verification code works fine!