Skip to content

Commit 68181fe

Browse files
author
frank
committed
Add documentation for implementing your own cookie validation.
1 parent f0524ad commit 68181fe

File tree

3 files changed

+56
-0
lines changed

3 files changed

+56
-0
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
## [Unreleased]
44
### Changed
5+
- feat: added addCookieSchema option, see docs/cookieValidationHowTo.md
56

67
## [4.6.1] 14-06-2024
78
### Changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@ The folder [examples/generated-javascript-project](examples/generated-javascript
182182
- fastify will by default coerce types, e.g when you expect a number a string like `"1"` will also pass validation, this can be reconfigured, see [Validation and Serialization](https://www.fastify.io/docs/latest/Reference/Validation-and-Serialization/).
183183
- fastify only supports one schema per route. So while the v3 standard allows for multiple content types per route, each with their own schema this is currently not going to work with fastify. Potential workarounds include a custom content type parser and merging schemas upfront using JSON schema `oneOf`.
184184
- the plugin aims to follow fastify and does not compensate for features that are possible according to the OpenApi specification but not possible in standard fastify (without plugins). This will keep the plugin lightweigth and maintainable. E.g. Fastify does not support cookie validation, while OpenApi v3 does.
185+
- in some cases however, the plugin may be able to provide you with data which could be used to enhance OpenApi support within your own Fastify application. Here is one possible way to perform [cookie validation](docs/cookieValidationHowTo.md) yourself.
185186
- if you have special needs on querystring handling (e.g. arrays, objects etc) then fastify supports a [custom querystring parser](https://www.fastify.io/docs/latest/Server/#querystringparser). You might need to pass the AJV option `coerceTypes: 'array'` as an option to Fastify.
186187
- the plugin is an ECMAscript Module (aka ESM). If you are using Typescript then make sure that you have read: https://www.typescriptlang.org/docs/handbook/esm-node.html to avoid any confusion.
187188
- If you want to use a specification that consists of multiple files then please check out the page on [subschemas](docs/subSchemas.md)

docs/cookieValidationHowTo.md

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
### Implementing cookie validation
2+
3+
The [OpenApi](https://www.openapis.org/) specification allows cookie validation, but Fastify itself does not validate or even parse cookies.
4+
5+
The `fastify-openapi-glue` plugin is intentionally designed to work without requiring additional 3rd party plugins.
6+
However, it does provide a boolean option `addCookieSchema` which tells it to insert JSON Schema describing OpenApi cookies into the Fastify [Routes options](https://fastify.dev/docs/latest/Reference/Routes/#routes-options).
7+
8+
Using this `addCookieSchema` option, one possible way to implement cookie validation in your application might be:
9+
- Register a plugin for cookie parsing with Fastify (perhaps [fastify cookie plugin](https://github.com/fastify/fastify-cookie)).
10+
- Listen for Fastify's [`onRoute` Application Hook](https://fastify.dev/docs/latest/Reference/Hooks/#onroute).
11+
- In your `onRoute` handler:
12+
- Check to see if `fastify-openapi-glue` found cookie specifications that it added to the `routeOptions`.
13+
- If cookie schema is present, pre-compile it with Ajv and add the compiled schema to the `routeOptions.config` object.
14+
- Register a global Fastify [`preHandler`](https://fastify.dev/docs/latest/Reference/Hooks/#prehandler)
15+
- In your global `preHandler`:
16+
- See if the invoked route has a cookie validator (pre-compiled by your `onRoute` handler).
17+
- Validate the cookie (which your cookie parser should have already added to the `request`).
18+
- With your customizations in place, register `fastify-openapi-glue`.
19+
20+
Example:
21+
```javascript
22+
// Register a plugin for cookie parsing
23+
fastify.register(cookie);
24+
25+
// Hook into the route registration process to compile cookie schemas
26+
fastify.addHook('onRoute', (routeOptions) => {
27+
const schema = routeOptions.schema;
28+
/*
29+
* schema.cookies will be added to the schema object if the
30+
* 'addCookieSchema' option is passed to fastify-openapi-glue.
31+
*/
32+
if (schema?.cookies) {
33+
// Compile the cookie schema and store it in the route's context
34+
routeOptions.config = routeOptions.config || {};
35+
routeOptions.config.cookieValidator = ajv.compile(schema.cookies);
36+
}
37+
});
38+
39+
// Pre-handler hook to validate cookies using the precompiled schema
40+
fastify.addHook('preHandler', async (request, reply) => {
41+
// See if this route has been configured with a cookie validator.
42+
const cookieValidator = request.routeOptions.config?.cookieValidator;
43+
if (cookieValidator) {
44+
const valid = cookieValidator(request.cookies);
45+
if (!valid) {
46+
reply.status(400).send({error: 'Invalid cookies', details: cookieValidator.errors});
47+
throw new Error('Invalid cookies');
48+
}
49+
}
50+
});
51+
52+
// Magic!
53+
fastify.register(openapiGlue, options);
54+
```

0 commit comments

Comments
 (0)