Reputation: 123410
As you may imagine, I'm familiar with Express, but this is the first time I'm using Fastify.
I'd like to access the unmodified body of a Fastify request, for signature verification of a webhook - ie, I would like to see the request as it came in, unmodified by any middleware. In Express this is often done by accessing request.rawBody
.
How do I access the raw body of a Fastify request?
Upvotes: 5
Views: 28519
Reputation: 216
According to the docs https://docs.nestjs.com/faq/raw-body
in main.ts
const app = await NestFactory.create<NestFastifyApplication>(
AppModule,
new FastifyAdapter(),
{
rawBody: true,
},
);
Then in your controller
async handleStripeEvent(
@Headers('stripe-signature') signature: string,
@Req() request: RawBodyRequest<FastifyRequest>,
) {
if (!signature) {
throw new BadRequestException('Missing stripe-signature header');
}
const event = await this.webhooksService.handleStripePaymentWebhook(
signature,
request.rawBody,
);
}
Upvotes: 4
Reputation: 653
You can also check this community plugin: https://github.com/Eomm/fastify-raw-body
If you are using Typescript & fastify/autoload, place this to plugins/rawbody.ts:
import fp from "fastify-plugin";
import rawbody, { RawBodyPluginOptions } from "fastify-raw-body";
export default fp<RawBodyPluginOptions>(async (fastify) => {
fastify.register(rawbody, {
field: "rawBody", // change the default request.rawBody property name
global: false, // add the rawBody to every request. **Default true**
encoding: "utf8", // set it to false to set rawBody as a Buffer **Default utf8**
runFirst: true, // get the body before any preParsing hook change/uncompress it. **Default false**
routes: [], // array of routes, **`global`** will be ignored, wildcard routes not supported
});
});
Since global:false
We need to configure it in the specific handler:
fastify.post<{ Body: any }>(
"/api/stripe_webhook",
{
config: {
// add the rawBody to this route. if false, rawBody will be disabled when global is true
rawBody: true,
},
},
async function (request, reply) {
...
Then you can access raw body in the handler using request.rawBody
Upvotes: 9
Reputation: 123410
Note: Fastify requests can only have req.body - they can't have, for example, req.body and req.rawBody like other web servers (for example, Express). This is because addContentTypeParser()
only returns a modified body
, it can't add anything else to the request.
Instead, in a content type parser we only add to one route, we make:
req.body.parsed
(the object, same content that would normally be in req.body)req.body.raw
(the string)See GitHub and the addContentTypeParser() docs for more.
server.addContentTypeParser(
"application/json",
{ parseAs: "string" },
function (req, body, done) {
try {
var newBody = {
raw: body,
parsed: JSON.parse(body),
};
done(null, newBody);
} catch (error) {
error.statusCode = 400;
done(error, undefined);
}
}
);
Upvotes: 4
Reputation: 417
There's an issue on GitHub for rawBody support
And there's a module too: "raw-body". To use this module in Fastify:
const rawBody = require('raw-body')
fastify.addContentTypeParser('*', (req, done) => {
rawBody(req, {
length: req.headers['content-length'],
limit: '1mb',
encoding: 'utf8', // Remove if you want a buffer
}, (err, body) => {
if (err) return done(err)
done(null, parse(body))
})
})
I hope that I helped you, I'm new on fastify too
Upvotes: 2