I'm developing an Express.js server; since it manages sensible data, I'd like to add a cryptographic signature to every response, using a private key. The signature part is already OK, the problem is catching the JSON string just before is sent to the client to sign it.
Ideally I'd like to add a custom response header, e.g. X-signature
, so clients could verify the received payload against the public key exposed by the service.
In Express, how can I intercept the response body after the JSON.stringify()
call but before the headers are sent?
I've copied what is done in the compression()
middleware, replacing the send()
method of Response with my own and calling the original one after I calculate the signature. Here's a simplified solution just to show the concept, in the real word I've taken care of body
's possible types. The fact that calculateSignature()
is an async function is a little troublesome, but everything seems to work well now.
Any comment is appreciated!
import express, { RequestHandler } from 'express';
declare const calculateSignature = (payload: string) => Promise<string>;
const responseSignature = (): RequestHandler => (_, res, next) => {
const _send = res.send;
res.send = (body) => {
if (isPlaintextType(body)) {
calculateSignature(body)
.then((signature) => res.setHeader('X-Signature', signature))
.catch((e) => console.error(e))
.finally(() => _send.call(res, body));
return res;
} else {
return _send.call(res, body);
}
};
next();
};
const app = express();
app.use(responseSignature());
app.listen(3000);