In there, the specified string to crypt is : App secret + http method + URI + request body (if present)
The code I’ve been trying in the following :
let stringToCrypt = `${config.hubspot.secretKey}${req.method}${req.url}`;
if (Object.keys(req.body).length) {
stringToCrypt += JSON.stringify(req.body);
}
console.log(stringToCrypt);
// (AppSecret)GET/?userId=(id)&userEmail=(email)&associatedObjectId=(Number)&associatedObjectType=...
const hash = crypto.createHash('sha256').update(stringToCrypt, 'utf8').digest('hex');
console.log('find : ', req.headers['x-hubspot-signature']);
console.log('hash : ', hash);
// those two don't match
The problem I have is that I do not have a example of a string juste before encryption, therefore I cannot
make sure I’m doing the right concatenation before crypting.
Therfore I might be mistaken on the different parts of the string :
AppSecret: Is the AppSecret the Client Secret or are the two of them distinct ?
URl : should it contain the base hostname (http://example.com) should it contain de query parameters ?
Body : How should I apply the body at the end of the string in case of a POST / PUT, is JSON.stringify the correct way add to the string ?
Sounds like you’re using Express? To my knowledge, the Express bodyParser module doesn’t return the raw request body by default (i.e. req.body isn’t the raw string, but parsed JSON). Looks like bodyparser includes a .text() method that returns the body as text instead:
Indeed, I was not adding the raw query but a string of a parsed json.
I did not want to change the content of my req.body so I’ve added a req.rawBodyString on this specific route just for request signature.
const rawBodySaver = (req, res, buf, encoding) => {
if (buf && buf.length) {
req.rawBodyString = buf.toString(encoding || 'utf8');
}
};
app.use('/api/hubspot', express.urlencoded({ verify: rawBodySaver, extended: false }));
app.use(express.urlencoded({ extended: false })); // This is used for other routes
I’m not directly using the bodyParser but the native express methods which are based on bodyParser.
It’s all working perfectly now so thanks a lot for your help on various topics, my CRM Extension is ready to go
Thanks for your help, I’ve got the verification to work for my GET requests (as they don’t have body), your answers for 1 & 2 worked fine, but I’m still not getting the right string to crypt when it comes to POST and PUT requests.
I’ve been trying to simply add a string of the body to my otherwise working string.
Yes, the app secret is the same as your app’s client secret
Yes, URI should be the full URI including everything
Depends on the request library you’re using. If req.body is a string, you should append it directly to stringToCrypt. If it’s interpreted by the request library as JSON, then you’ll need to stringify it first. If you’re JSON.stringify()-ing a string, it might end up malformed.