2019-05-06 16:17:16 +02:00
# Middlewares
The middlewares are functions which are composed and executed in a stack-like manner upon request. If you are not familiar with the middleware stack in Koa, we highly recommend you to read the [Koa's documentation introduction ](http://koajs.com/#introduction ).
2020-04-01 11:48:38 +02:00
## Structure
2019-05-06 16:17:16 +02:00
2020-04-01 11:48:38 +02:00
### File structure
2019-05-06 16:17:16 +02:00
```js
module.exports = strapi => {
return {
2019-06-08 18:50:07 +02:00
// can also be async
initialize() {
2019-05-06 16:17:16 +02:00
strapi.app.use(async (ctx, next) => {
2020-04-01 11:48:38 +02:00
// await someAsyncCode()
2019-05-06 16:17:16 +02:00
await next();
2020-04-01 11:48:38 +02:00
// await someAsyncCode()
2019-05-06 16:17:16 +02:00
});
},
};
};
```
2019-06-08 18:50:07 +02:00
- `initialize` (function): Called during the server boot.
2019-05-06 16:17:16 +02:00
2020-04-01 11:48:38 +02:00
The middlewares are accessible through the `strapi.middleware` variable.
2019-05-06 16:17:16 +02:00
2020-04-01 11:48:38 +02:00
### Node modules
2019-05-06 16:17:16 +02:00
2020-04-01 11:48:38 +02:00
Every folder that follows this name pattern `strapi-middleware-*` in your `./node_modules` folder will be loaded as a middleware.
2019-05-06 16:17:16 +02:00
A middleware needs to follow the structure below:
```
/middleware
└─── lib
- index.js
- LICENSE.md
- package.json
- README.md
```
The `index.js` is the entry point to your middleware. It should look like the example above.
2020-04-01 11:48:38 +02:00
### Custom middlewares
2019-05-06 16:17:16 +02:00
The framework allows the application to override the default middlewares and add new ones. You have to create a `./middlewares` folder at the root of your project and put the middlewares into it.
```
/project
└─── api
└─── config
└─── middlewares
2020-02-08 19:37:00 +01:00
│ └─── responseTime // It will override the core default responseTime middleware.
2019-05-06 16:17:16 +02:00
│ - index.js
2020-02-08 19:37:00 +01:00
│ └─── views // It will be added into the stack of middleware.
2019-05-06 16:17:16 +02:00
│ - index.js
└─── public
- favicon.ico
- package.json
- server.js
```
Every middleware will be injected into the Koa stack. To manage the load order, please refer to the [Middleware order section ](#load-order ).
2020-04-01 11:48:38 +02:00
## Configuration and activation
2020-04-29 11:24:05 +02:00
To configure the middlewares of your application, you need to create or edit the `./config/middleware.js` file in your Strapi app.
2020-04-01 11:48:38 +02:00
2020-04-09 11:41:55 +02:00
By default this file doesn't exist, you will have to create it.
2020-04-29 11:24:05 +02:00
**Availabe options**
2020-04-10 10:40:27 +02:00
- `timeout` (integer): Defines the maximum allowed milliseconds to load a middleware.
- `load` (Object): Configuration middleware loading. See details [here ](#load-order )
- `settings` (Object): Configuration of each middleware
- `{middlewareName}` (Object): Configuration of one middleware
- `enabled` (boolean): Tells Strapi to run the middleware or not
2020-04-01 11:48:38 +02:00
2020-04-10 10:40:27 +02:00
## Core middleware configurations
2020-04-01 11:48:38 +02:00
The core of Strapi embraces a small list of middlewares for performances, security and great error handling.
- boom
- cors
- cron
- csp
- favicon
- gzip
- hsts
- ip
- language
- logger
- p3p
- parser
- public
- responses
- responseTime
- router
- session
- xframe
- xss
::: tip
The following middlewares cannot be disabled: responses, router, logger and boom.
:::
2020-04-10 10:40:27 +02:00
### Global middlewares
- `favicon`
- `path` (string): Path to the favicon file. Default value: `favicon.ico` .
- `maxAge` (integer): Cache-control max-age directive in ms. Default value: `86400000` .
- `public`
- `path` (string): Path to the public folder. Default value: `./public` .
- `maxAge` (integer): Cache-control max-age directive in ms. Default value: `60000` .
- `defaultIndex` (boolean): Display default index page at `/` and `/index.html` . Default value: `true` .
### Request middlewares
- `session`
- `enabled` (boolean): Enable or disable sessions. Default value: `false` .
- `client` (string): Client used to persist sessions. Default value: `redis` .
- `settings`
- `host` (string): Client host name. Default value: `localhost` .
- `port` (integer): Client port. Default value: `6379` .
- `database` (integer)|String - Client database name. Default value: `10` .
- `password` (string): Client password. Default value: ``.
- `logger`
- `level` (string): Default log level. Default value: `debug` .
- `exposeInContext` (boolean): Expose logger in context so it can be used through `strapi.log.info(‘ my log’ )` . Default value: `true` .
- `requests` (boolean): Enable or disable requests logs. Default value: `false` .
- `parser`
- `enabled` (boolean): Enable or disable parser. Default value: `true` .
- `multipart` (boolean): Enable or disable multipart bodies parsing. Default value: `true` .
::: tip
The session doesn't work with `mongo` as a client. The package that we should use is broken for now.
:::
## Response middlewares
- [`gzip` ](https://en.wikipedia.org/wiki/Gzip )
- `enabled` (boolean): Enable or not GZIP response compression.
- `responseTime`
- `enabled` (boolean): Enable or not `X-Response-Time header` to response. Default value: `false` .
- `poweredBy`
- `enabled` (boolean): Enable or not `X-Powered-By` header to response. Default value: `true` .
- `value` (string): The value of the header. Default value: `Strapi <strapi.io>`
### Security middlewares
- [`csp` ](https://en.wikipedia.org/wiki/Content_Security_Policy )
- `enabled` (boolean): Enable or disable CSP to avoid Cross Site Scripting (XSS) and data injection attacks.
- [`p3p` ](https://en.wikipedia.org/wiki/P3P )
- `enabled` (boolean): Enable or disable p3p.
- [`hsts` ](https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security )
- `enabled` (boolean): Enable or disable HSTS.
- `maxAge` (integer): Number of seconds HSTS is in effect. Default value: `31536000` .
- `includeSubDomains` (boolean): Applies HSTS to all subdomains of the host. Default value: `true` .
- [`xframe` ](https://en.wikipedia.org/wiki/Clickjacking )
- `enabled` (boolean): Enable or disable `X-FRAME-OPTIONS` headers in response.
- `value` (string): The value for the header, e.g. DENY, SAMEORIGIN or ALLOW-FROM uri. Default value: `SAMEORIGIN` .
- [`xss` ](https://en.wikipedia.org/wiki/Cross-site_scripting )
- `enabled` (boolean): Enable or disable XSS to prevent Cross Site Scripting (XSS) attacks in older IE browsers (IE8).
- [`cors` ](https://en.wikipedia.org/wiki/Cross-origin_resource_sharing )
- `enabled` (boolean): Enable or disable CORS to prevent your server to be requested from another domain.
2020-04-21 16:24:25 +02:00
- `origin` (string): Allowed URLs (`http://example1.com, http://example2.com` or allows everyone `*` ). Default value: `*` .
2020-04-10 10:40:27 +02:00
- `expose` (array): Configures the `Access-Control-Expose-Headers` CORS header. If not specified, no custom headers are exposed. Default value: `["WWW-Authenticate", "Server-Authorization"]` .
- `maxAge` (integer): Configures the `Access-Control-Max-Age` CORS header. Default value: `31536000` .
- `credentials` (boolean): Configures the `Access-Control-Allow-Credentials` CORS header. Default value: `true` .
- `methods` (array)|String - Configures the `Access-Control-Allow-Methods` CORS header. Default value: `["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS", "HEAD"]` .
- `headers` (array): Configures the `Access-Control-Allow-Headers` CORS header. If not specified, defaults to reflecting the headers specified in the request's Access-Control-Request-Headers header. Default value: `["Content-Type", "Authorization", "X-Frame-Options"]` .
- `ip`
- `enabled` (boolean): Enable or disable IP blocker. Default value: `false` .
- `whiteList` (array): Whitelisted IPs. Default value: `[]` .
- `blackList` (array): Blacklisted IPs. Default value: `[]` .
2020-04-21 16:24:25 +02:00
**Example**:
**Path —** `./config/middleware.js` .
```js
module.exports = {
//...
settings: {
cors: {
origin: 'http://localhost',
},
},
};
```
2020-04-01 11:48:38 +02:00
### Load order
2019-05-06 16:17:16 +02:00
2020-04-29 11:24:05 +02:00
The middlewares are injected into the Koa stack asynchronously. Sometimes it happens that some of these middlewares need to be loaded in a specific order. To define a load order, create or edit the file `./config/middleware.js` .
2019-05-06 16:17:16 +02:00
2020-04-10 10:40:27 +02:00
**Path —** `./config/middleware.js` .
2019-05-06 16:17:16 +02:00
2020-04-10 10:40:27 +02:00
```js
module.exports = {
load: {
before: ['responseTime', 'logger', 'cors', 'responses'],
order: [
"Define the middlewares' load order by putting their name in this array in the right order",
2019-05-06 16:17:16 +02:00
],
2020-04-10 10:40:27 +02:00
after: ['parser', 'router'],
},
};
2019-05-06 16:17:16 +02:00
```
- `load` :
2020-02-08 19:37:00 +01:00
- `before` : Array of middlewares that need to be loaded in the first place. The order of this array matters.
- `order` : Array of middlewares that need to be loaded in a specific order.
- `after` : Array of middlewares that need to be loaded at the end of the stack. The order of this array matters.
2019-05-06 16:17:16 +02:00
2020-04-01 11:48:38 +02:00
### Examples
2019-05-06 16:17:16 +02:00
2020-04-01 11:48:38 +02:00
Create your custom middleware.
2019-05-06 16:17:16 +02:00
2020-04-01 11:48:38 +02:00
**Path —** `./middlewares/timer/index.js`
2019-05-06 16:17:16 +02:00
2020-04-01 11:48:38 +02:00
```js
module.exports = strapi => {
return {
initialize() {
strapi.app.use(async (ctx, next) => {
const start = Date.now();
2019-05-06 16:17:16 +02:00
2020-04-01 11:48:38 +02:00
await next();
2019-05-06 16:17:16 +02:00
2020-04-01 11:48:38 +02:00
const delta = Math.ceil(Date.now() - start);
2019-05-06 16:17:16 +02:00
2020-04-01 11:48:38 +02:00
ctx.set('X-Response-Time', delta + 'ms');
});
},
};
};
2019-05-06 16:17:16 +02:00
```
2020-04-01 11:48:38 +02:00
Enable the middleware in environments settings.
2019-05-06 16:17:16 +02:00
2020-04-01 11:48:38 +02:00
Load a middleware at the very first place
2019-05-06 16:17:16 +02:00
2020-04-10 10:40:27 +02:00
**Path —** `./config/middleware.js`
2019-05-06 16:17:16 +02:00
2020-04-10 10:40:27 +02:00
```js
module.exports = {
load: {
before: ['timer', 'responseTime', 'logger', 'cors', 'responses', 'gzip'],
order: [
"Define the middlewares' load order by putting their name in this array is the right order",
2020-04-01 11:48:38 +02:00
],
2020-04-10 10:40:27 +02:00
after: ['parser', 'router'],
},
settings: {
timer: {
enabled: true,
},
},
};
2019-05-06 16:17:16 +02:00
```