Alexa Request Verifier Middleware for Express

raw JSON →
2.1.0 verified Thu Apr 23 auth: no javascript

alexa-verifier-middleware is an Express.js middleware designed to verify incoming HTTP requests to an Alexa skill endpoint, ensuring they originate from Amazon. The package is currently stable at version 2.1.0, though the README indicates a 3.x branch exists which is pure ESM. The release cadence appears to follow semantic versioning with major updates indicating breaking changes, such as the transition to ES modules. Its primary differentiator is its focused role in securing Alexa skill endpoints by verifying request authenticity, building upon the `alexa-verifier` module. This middleware is crucial for preventing spoofed requests and maintaining the security posture of an Alexa skill's backend service.

error The raw request body has already been parsed.
cause Another middleware (e.g., `body-parser`) parsed the request body before `alexa-verifier-middleware` could access it for verification.
fix
Place alexaRouter.use(verifier) *before* any body parsing middlewares like alexaRouter.use(bodyParser.json()).
error TypeError: verifier is not a function
cause Attempting to `require()` an ESM-only version (3.x+) of the package in a CommonJS context, or an incorrect import statement for ESM.
fix
If using v3.x+, ensure your project is configured for ESM ("type": "module" in package.json) and use import verifier from 'alexa-verifier-middleware'. If using an older Node.js or CommonJS, use v2.x or earlier and const verifier = require('alexa-verifier-middleware').
breaking Version 3.x of alexa-verifier-middleware is a pure ES module. This means it can only be imported using `import` statements and is incompatible with CommonJS `require()` without specific configuration (e.g., dynamic import or build tooling).
fix Migrate your project to use ES modules by adding `"type": "module"` to your `package.json` and using `import` statements, or stick to version 2.x for CommonJS compatibility.
gotcha The `alexa-verifier-middleware` must be loaded *before* any other middleware that parses the request body (e.g., `express.json()`, `body-parser`). The verifier requires access to the raw request body for signature verification.
fix Ensure `app.use(verifier)` or `router.use(verifier)` is called before any `app.use(express.json())` or `app.use(bodyParser.json())` calls for the affected routes.
gotcha The package requires Node.js version 12.17 or higher for versions 3.x. Older versions of Node.js are incompatible with the ES module syntax and features used.
fix Upgrade your Node.js environment to 12.17 or newer, or use `alexa-verifier-middleware@1.x` if you need to support older Node.js versions.
npm install alexa-verifier-middleware
yarn add alexa-verifier-middleware
pnpm add alexa-verifier-middleware

This quickstart demonstrates how to set up an Express.js server with the alexa-verifier-middleware, ensuring that incoming Alexa requests are validated before being processed by your skill's logic.

import express from 'express';
import verifier from 'alexa-verifier-middleware';

const app = express();
const alexaRouter = express.Router();

// Create a router and attach to express before doing anything else
app.use('/alexa', alexaRouter);

// Attach the verifier middleware first because it needs the entire
// request body, and express doesn't expose this on the request object.
alexaRouter.use(verifier);

// Add a body parser AFTER the verifier if needed for other routes or POST bodies.
alexaRouter.use(express.json()); 

// Define your Alexa skill endpoint
alexaRouter.post('/skill-endpoint', (req, res) => {
  // In a real skill, you would process the Alexa request body here.
  // For this example, we just acknowledge receipt.
  console.log('Received Alexa request:', req.body);
  res.json({
    version: '1.0',
    response: {
      outputSpeech: {
        type: 'PlainText',
        text: 'Hello from your skill!'
      }
    }
  });
});

const PORT = process.env.PORT ?? 3000;
app.listen(PORT, () => {
  console.log(`Alexa skill listening on port ${PORT}`);
});