Sails is fully compatible with Express / Connect middleware - in fact, it's all over the place! Much of the code you'll write in Sails is effectively middleware; most notably controller actions and policies.
Sails also utilizes an additional configurable middleware stack just for handling HTTP requests. Each time your app receives an HTTP request, the configured HTTP middleware stack runs in order.
Read about the default middleware stack here.
Note that this HTTP middleware stack is only used for "true" HTTP requests-- it is ignored for virtual requests (e.g. requests from a live Socket.io connection.)
To configure a custom HTTP middleware function, define a new HTTP key sails.config.http.middleware.foobar
and set it to the configured middleware function, then add the string name ("foobar") to your sails.config.http.middleware.order
array wherever you'd like it to run in the middleware chain (a good place to put it might be right before "cookieParser"):
E.g. in config/http.js
:
// ...
middleware: {
// Define a custom HTTP middleware fn with the key `foobar`:
foobar: function (req,res,next) { /*...*/ next(); },
// Define another couple of custom HTTP middleware fns with keys `passportInit` and `passportSession`
// (notice that this time we're using an existing middleware library from npm)
passportInit : require('passport').initialize(),
passportSession : require('passport').session(),
// Override the conventional cookie parser:
cookieParser: function (req, res, next) { /*...*/ next(); },
// Now configure the order/arrangement of our HTTP middleware
order: [
'startRequestTimer',
'cookieParser',
'session',
'passportInit', // <==== passport HTTP middleware should run after "session"
'passportSession', // <==== (see https://github.com/jaredhanson/passport#middleware)
'bodyParser',
'compress',
'foobar', // <==== we can put this stuff wherever we want
'methodOverride',
'poweredBy',
'$custom',
'router',
'www',
'favicon',
'404',
'500'
]
},
customMiddleware: function(app){
//Intended for other middleware that doesn't follow 'app.use(middleware)' convention
require('other-middleware').initialize(app);
}
// ...
One of the really nice things about Sails apps is that they can take advantage of the wealth of already-existing Express/Connect middleware out there. But a common question that arises when people actually try to do this is:
"Where do I
app.use()
this thing?".
In most cases, the answer is to install the Express middleware as a custom HTTP middleware in sails.config.http.middleware
. This will trigger it for ALL HTTP requests to your Sails app, and allow you to configure the order in which it runs in relation to other HTTP middleware.
You should never override or remove the
router
HTTP middleware. It is built-in to Sails, and without it, your app's explicit routes and blueprint routes will not work.
You can also include Express middleware as a policy- just configure it in config/policies.js
. You can either require and setup the middleware in an actual wrapper policy (usually a good idea) or just require it directly in your policies.js file. The following example uses the latter strategy for brevity:
var auth = require('http-auth');
var basic = auth.basic({
realm: 'admin area'
}, function (username, password, onwards) {
return onwards(username === 'Tina' && password === 'Bullock');
});
//...
module.exports.policies = {
'*': true,
ProductController: {
// Prevent end users from doing CRUD operations on products reserved for admins
// (uses HTTP basic auth)
'*': auth.connect(basic),
// Everyone can view product pages
show: true
}
}