When a user submits a form on my site, it triggers a HTTP post hook using Netlify notifications. Then, I want to verify this post using JWT.
The post hook has JWS secret token, which is a random string, the same as process.env.JWS_SECRET
in my deploy.
The post request is then handled by a Next.js API route that looks like this:
import { createHmac } from "crypto";
import jwt from "jsonwebtoken";
const secret = process.env.JWS_SECRET;
const signed = (signature, body) => {
try {
const decoded = jwt.verify(signature, secret, {
algorithms: ["HS256"],
issuer: "netlify",
});
const hash = createHmac("sha256", secret).update(body).digest("hex");
return decoded.sha256 === hash;
} catch (error) {
return false;
}
};
export default async function handler(req, res) {
if (req.method === "POST") {
const signature = req.headers.["x-webhook-signature"];
const formData = req.body;
if (!signed(signature, req.body)) {
return res.status(403).json({ message: "Invalid" });
}
// do something here
} else {
// method not allowed
}
}
I’m adapting the Ruby code provided here Deploy notifications | Netlify Docs.
But the decoded.sha256 === hash
line returns false. What am I doing wrong in the verification?
Update:
I’ve tried using this instead, which I think is actually the right way to do it, but still no luck:
const hash = createHash("sha256").update(JSON.stringify(body)).digest("hex");