# 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 (opens new window).
# Structure
# File structure
module.exports = strapi => {
return {
// can also be async
initialize() {
strapi.app.use(async (ctx, next) => {
// await someAsyncCode()
await next();
// await someAsyncCode()
});
},
};
};
initialize
(function): Called during the server boot.
The middlewares are accessible through the strapi.middleware
variable.
# Node modules
Every folder that follows this name pattern strapi-middleware-*
in your ./node_modules
folder will be loaded as a middleware.
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.
# Custom middlewares
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
│ └─── responseTime // It will override the core default responseTime middleware.
│ - index.js
│ └─── views // It will be added into the stack of middleware.
│ - 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.
# Configuration and activation
To configure the middlewares of your application, you need to create or edit the ./config/middleware.js
file in your Strapi app.
By default this file doesn't exist, you will have to create it.
Available options
timeout
(integer): Defines the maximum allowed milliseconds to load a middleware.load
(Object): Configuration middleware loading. See details heresettings
(Object): Configuration of each middleware{middlewareName}
(Object): Configuration of one middlewareenabled
(boolean): Tells Strapi to run the middleware or not
# Settings
Example:
Path — ./config/middleware.js
.
module.exports = {
//...
settings: {
cors: {
origin: ['http://localhost', 'https://mysite.com', 'https://www.mysite.com'],
},
},
};
# Load order
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
.
Path — ./config/middleware.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",
],
after: ['parser', 'router'],
},
};
load
: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.
# Core middleware configurations
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.
# 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
.
logger
level
(string): Default log level. Default value:debug
.exposeInContext
(boolean): Expose logger in context so it can be used throughstrapi.log.info(‘my log’)
. Default value:true
.requests
(boolean): Enable or disable requests logs. Default value:false
.
parser
(See koa-body (opens new window) for more information)enabled
(boolean): Enable or disable parser. Default value:true
.multipart
(boolean): Enable or disable multipart bodies parsing. Default value:true
.jsonLimit
(string|integer): The byte (if integer) limit of the JSON body. Default value:1mb
.formLimit
(string|integer): The byte (if integer) limit of the form body. Default value:56k
.queryStringParser
(see qs (opens new window) for a full list of options).arrayLimit
(integer): the maximum length of an array in the query string. Any array members with an index of greater than the limit will instead be converted to an object with the index as the key. Default value:100
.depth
(integer): maximum parsing depth of nested query string objects. Default value:20
.
TIP
The session doesn't work with mongo
as a client. The package that we should use is broken for now.
# Response middlewares
gzip
(opens new window)enabled
(boolean): Enable or not GZIP response compression.options
(Object): Allow passing of options from koa-compress (opens new window).
responseTime
enabled
(boolean): Enable or notX-Response-Time header
to response. Default value:false
.
poweredBy
enabled
(boolean): Enable or notX-Powered-By
header to response. Default value:true
.value
(string): The value of the header. Default value:Strapi <strapi.io>
TIP
gzip
compression via koa-compress
uses Brotli (opens new window) by default, but is not configured with sensible defaults for most cases. If you experience slow response times with gzip
enabled, consider disabling Brotli by passing {br: false}
as an option. You may also pass more sensible params with {br: { params: { // YOUR PARAMS HERE } }}
# Security middlewares
csp
(opens new window)enabled
(boolean): Enable or disable CSP to avoid Cross Site Scripting (XSS) and data injection attacks.policy
(string): Configures theContent-Security-Policy
header. If not specified uses default value. Default value:undefined
.
p3p
(opens new window)enabled
(boolean): Enable or disable p3p.
hsts
(opens new window)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
(opens new window)enabled
(boolean): Enable or disableX-FRAME-OPTIONS
headers in response.value
(string): The value for the header, e.g. DENY, SAMEORIGIN or ALLOW-FROM uri. Default value:SAMEORIGIN
.
xss
(opens new window)enabled
(boolean): Enable or disable XSS to prevent Cross Site Scripting (XSS) attacks in older IE browsers (IE8).
cors
(opens new window)enabled
(boolean): Enable or disable CORS to prevent your server to be requested from another domain.origin
(string or array): Allowed URLs (http://example1.com, http://example2.com
,['http://www.example1.com', 'http://example1.com']
or allows everyone*
). Default value:*
.expose
(array): Configures theAccess-Control-Expose-Headers
CORS header. If not specified, no custom headers are exposed. Default value:["WWW-Authenticate", "Server-Authorization"]
.maxAge
(integer): Configures theAccess-Control-Max-Age
CORS header. Default value:31536000
.credentials
(boolean): Configures theAccess-Control-Allow-Credentials
CORS header. Default value:true
.methods
(array)|String - Configures theAccess-Control-Allow-Methods
CORS header. Default value:["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS", "HEAD"]
.headers
(array): Configures theAccess-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:[]
.
# Example
Create your custom middleware.
Path — ./middlewares/timer/index.js
module.exports = strapi => {
return {
initialize() {
strapi.app.use(async (ctx, next) => {
const start = Date.now();
await next();
const delta = Math.ceil(Date.now() - start);
ctx.set('X-Response-Time', delta + 'ms');
});
},
};
};
Enable the middleware in environments settings.
Load a middleware at the very first place
Path — ./config/middleware.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",
],
after: ['parser', 'router'],
},
settings: {
timer: {
enabled: true,
},
},
};