How AI-ready is your team? Take our AI Readiness Assessment to find out how you score — now live.

Securing Webhooks: Verifying Signatures in Different Technologies

Storyblok is the first headless CMS that works for developers & marketers alike.

Webhooks enable real-time communication between applications, but they must be secured to prevent unauthorized access. Storyblok sends a webhook-signature header with each webhook request, which can be verified using a shared secret key (webhook secret) configured when setting up the webhook.

Setting Up a Webhook in Storyblok

Before implementing signature verification, ensure you have created a webhook in Storyblok. Learn more in our webhooks documentation.

Learn:

Many JavaScript frameworks automatically parse incoming JSON data, but Storyblok sends webhook payloads as raw text. To avoid issues, ensure your framework processes the payload without automatic JSON parsing. Check its documentation for accessing raw request bodies and use middleware or built-in methods to handle raw payloads properly.

Verifying Webhook Signatures in Different Technologies

Verfify webhook signature - Nodejs + Express
import express from 'express'
import { createHmac } from 'node:crypto'

const app = express()
const port = 4000

//Adding a new property in the request called rawBody with unparsed data
app.use(function (req, res, next) {
  req.rawBody = ''
  req.setEncoding('utf8')
  req.on('data', function (chunk) {
    req.rawBody += chunk
  })
  req.on('end', function () {
    next()
  })
})

//If you are using something like body parser for your project use it here

app.get('/', (req, res) => {
  res.send('Hello World!')
})
app.post('/', async (req, res) => {
  const payload = req.rawBody
  const signature = req.headers['webhook-signature']
  const webhookSecret = 'hello' //What you used in Storyblok
  const generatedSignature = createHmac('sha1', webhookSecret)
    .update(payload)
    .digest('hex')
  const isValid = generatedSignature === signature
  if (isValid) {
    //you logic goes here
  }
  res.json({ isValid, generatedSignature, signature, payload })
})

app.listen(port, () => {
  console.log(`Example app listening on port ${port}`)
})
Learn:

If you encounter issues with webhook verification, check the webhook logs in your Storyblok settings to view request details, including payloads and headers. You can also use external tools like webhook.site or RequestBin to inspect webhook requests in real-time for easier debugging.

Implementing signature verification ensures that only valid requests from Storyblok are processed, enhancing security and preventing unauthorized data access.

Author

Dipankar Maikap

Dipankar Maikap

Dipankar Maikap is a Developer Experience Engineer at Storyblok, with a background in Developer Relations and Documentation Engineering. He focuses on frontend development, modern JavaScript frameworks, and improving developer tooling and documentation.