I have been reading documents/urls and really not understand about app.use and its usage.
I understand that it is part of connect but I am really not getting that.
Example:
// ignore GET /favicon.ico
app.use(express.favicon());
// add req.session cookie support
app.use(express.cookieSession());
// do something with the session
app.use(count);
can you please explain me all these 3 . what they mean?
does this mean based on (1) that
app.use is noting but => app.get?
app.use(count) what and when is this count be executed (or) called/
Looks Basic but did not get the answers
// ignore GET /favicon.ico
app.use(express.favicon());
// pass a secret to cookieParser() for signed cookies
app.use(express.cookieParser('manny is cool'));
// add req.session cookie support
app.use(express.cookieSession());
// do something with the session
app.use(count);
// custom middleware
function count(req, res) {
When you call app.use(), you pass in a function to handle requests. As requests come in, Express goes through all of the functions in order until the request is handled.
express.favicon is a simple function that returns favicon.ico when it is requested. It's actually a great example for how to get started with this pattern. You can view the source code by looking at its source: node_modules/express/node_modules/connect/lib/middleware/favicon.js
express.cookieSession is some more middleware for supporting session data, keyed from the client by a cookie.
I don't know what count does... is that your own code? In any case, let me know if this is not clear.
Related
I am overall clueless about how and why you set up a node.js app, and how any of the app.use functions work - the tutorials on it don't explain the why of anything.
Anyway, I have socket.io, res.locals and index.js set up like so in the app.js root file.
const sockets = require('./models/socket')(io)
app.use(function (req, res, next) {
res.locals.user_id = req.session.user_id;
next();
});
const routes = require('./routes/index');
app.use('/', routes);
I'd like to be able to access res.locals in the socket.js model, like I can in index.js found in the routes folder.
I can't guess how to go about doing this. If anybody is able to explain how and why I can or can't that would be a bonus. Thanks!
Welcome to Expressjs, there are a few fundamentals you should probably research before going any further, they'll help solve some of your confusion. I'll give a brief explanation of them but I suggest you do further research. I'll then answer your actual question at the end.
Middleware and app.use
Expressjs is built upon an idea that everything is just "middleware". Middleware is a function which runs as part of a request chain. A request chain is essentially a single client request, which then goes through a chain of a number of middleware functions until it either reaches the end of the chain, exits early by returning a response to the client, or errors.
Express middleware is a function which takes the following three arguments.
req (request) - Representing the request made by a client to your
server.
res (response) - Representing the response you will return to
the client.
next - A way of telling express that your current
middleware function is done, and it should now call the next piece of
middleware. This can either be called "empty" as next(); or with an
error next(new Error());. If it is called empty, it will trigger
the next piece of middleware, if it is called with an error then it
will call the first piece of error middleware. If next is not called at the
end of a piece of middleware, then the request is deemed finished and the
response object is sent to the user.
app.use is a way of setting middleware, this means it will run for every request (unless next() is either not called by the previous piece of middleware for some reason, or it's called with an error). This middleware will run for any HTTP request type (GET, POST, PUT, DELETE, etc).
app.use can take multiple arguments, the important ones for beginners to learn are: app.use(func) and app.use(path, func). The former sets "global" middleware which runs no matter what endpoint (url path) the client requests, the latter (with a specific path) is run only if that specific path is hit. I.e. app.use('/hello', (req, res, next) => { res.send('world'); }); will return "world" when the endpoint "/hello" is hit, but not if the client requests "/hi". Where as app.use((req, res, next) => { res.send('world'); }); would return "world" when you hit any endpoint.
There are more complex things you can do with this, but that's the basics of attaching middleware to your application. The order they are attached to the application, is the order in which they will run.
One more thing, this will blow your mind, an express application made with the standard const app = express() can also be used as middleware. This means you can create several express applications, and then mount them using app.use to a single express application. This is pretty advanced, but does allow you to do some really great things with Express.
Why can you not access res.locals in socket.io? (The real question)
Within your middleware handler, you are setting up a res.locals.use_id property. This only lives with that individual request, you can pass it around as long as the request is alive by passing it into other functions, but outside of that request it doesn't exist. res is literally the response object that tells Express how to respond to the clients request, you can set properties of it during the request but once that HTTP request has ended it's gone.
Socket.io is a way of handling web socket requests, not standard HTTP requests. Thus, in a standard express HTTP request you will not be able to hand off the connection to anything with socket.io, because the connection is a single short lived HTTP request. Likewise, you won't be able to do the same the other way.
If you wish to find the users id in a socket.io request, you'll have to do this within the socket.io request itself.
Right now, you're entering a piece of middleware for an Express.js request, you are then calling next() which runs the next piece of express middleware, at no point does it cross over into Socket.io realms. This is often confused by tutorials because Socket.io can handle requests across the same port as Express is listening on, but the two are not crossed over. So you will need to write separate middleware for both Express.js requests chains, and socket.io request chains. There are ways of writing this code once and then writing an adapter to use it across both platforms, but that's not what you've tried to do here.
I would suggest you look at doing just nodejs and express for a time before taking on socket.io as well, otherwise you're trying to learn a whole heap of technologies all at once is quite a lot to try and take on board all at once.
Backstory: I'm trying to debug an issue in one piece of middleware that I think is coming from other piece. But, I'm not sure. So anyway, I would like to be able to check what middleware is actually being called, because I'm not sure of the ordering.
Is it possible to inspect the set of middleware that is currently being used?
I have tried to find any piece of internal state where Express might be storing the middleware, but I was not able to.
You can't see what is specifically "middleware", but you can inspect all registered handlers.
In express 4:
// Routes registered on app object
app._router.stack
// Routes registered on a router object
router.stack
Fine for inspection/debugging, probably not a great idea to program against any variable prefaced with an underscore.
How middleware works:
The middlewares are generally used to transform a request or response object, before it reaches to other middlewares.
If you are concerned with the order in which the middlewares are called, express calls the middleware, in the order in which they are defined.
Example,
app.use(compression());
app.use(passport.initialize());
app.use(bodyParser());
app.use(cookieParser());
the order is
compression,
passport,
bodyParser,
cookieParser
(plus I think your bodyParser and cookieParser middlewares should be before the other middlewares like passport).
That is the reason why the error handling middlewares are kept at last, so that if it reaches them, they give an error response.
So basically, request drips down the middlewares until one of them says that it does not want it to go any further(get, post methods are such middlewares, that stop the request).
Now, the debugging part:
You may not be able to inspect the middleware properly internally, but you can check whether middleware has worked properly by inserting your own custom middleware in between and then put a breakpoint on it.
Let's say you want is to debug what happened to your request after the bodyParser middlewares does it tasks, you can do is put your custom middleware in between and check the request and response whether they are modified properly or not.
how you do this is by following example.
Example,
app.use(bodyParser());
//custom middleware to inspect which middleware is not working properly
app.use(function(req,res,next){
console.log("check something!"); //do something here/put a breakpoint
next();
/*this function is the third parameter
and need to be called by the middleware
to proceed the request to the next middleware,
if your don't write this line, your reqest will just stop here.
app.get/app.post like methods does not call next*/
});
app.use(cookieParser());
This is one way in which you move this custom debugger in between the middlewares, until you figure out which one is giving faulty outputs.
Also, if you want to check the middlewares functionality, you can look at the documentation of those middlewares. They are quite good.
Check by playing with your custom middleware.
The problem is the following: On the deployed nodejitsu app, often (not always!), when I redirect from the browser (clicks on a a href="/logout") to the /logout route, i get a req.session undefined within that route.
app.get('/logout', function(req, res){
log.debug("session", req.session); //undefined
});
The requests go through the following stack of 'middleware':
var store = new db.store({client: db.client}); // no problems here, redis monitor confirms
app.configure(function(){
[...]
app.use(express.cookieParser("XXXpassXXX"));
app.use(express.bodyParser());
app.use(express.session({
secret: "XXXpassXXX",
store: store
}));
app.use(function(req, res, next) {
var fullURL = req.protocol + "://" + req.get('host') + req.url;
if (fullURL.indexOf("logout") != -1 || fullURL[fullURL.length-1] == "/") {
log.debug(fullURL);
log.debug("sesiune", JSON.stringify(req.session)); // undefined for the "/logout" route !!!
log.debug("cookies", JSON.stringify(req.cookies));
}
next();
});
app.use(passport.session());
app.use(app.router);
});
I have checked the browser and it sends the cookies to the server and in my "logger" middleware, i can see the fullURL is correctly set.
Also, the last query made to the redis db by the app, before failing, is a get "sess:xxx" on the correct session id (which is stored in the database correctly).
Why and what could be the reasons that, after after express.session() using connect-redis as a store submits to the next() middleware, the req.session is undefined, given the fact that the session is stored on the redis database and it DOES perform a "get" on it?
PS: While on the local server, with a local redis instance, everything works.
It looks like you're doing everything right, so I'm afraid I don't have a direct answer for you. However, I hope this will help you debug the problem.
The first thing I would do is look at the various failure conditions in the session middleware, and see if any of them might be an issue in your production environment. That code is located in your project directory here:
node_modules/express/node_modules/connect/middleware/session.js
Look for the line starting with function session(options){; that's where the party starts. About 25 lines later, you'll see return function session(req, res, next){; that's the actual middleware. If you browse through that source, you'll see various reasons why the session variable might not be set (anything that throws an error or returns next()). For example, the store can be disconnected, or there's a pathname mismatch. Sometimes, debug() is called on failure, so you could try enabling debugging logging. Just set the environment variable DEBUG to express:*. I haven't used Nodejitsu yet, but I'm sure there's a way you can set environment variables and examine your logs.
If you can enable remote debugging on Nodejitsu, then even better: that way you could actually step through the session middleware and find out where it's failing (or if it's not getting called for some reason). I looked through the public Nodejitsu documentation, and didn't see anything about remote debugging, but that doesn't mean it can't be done.
So I've seen TJ's guide to creating modular Express-apps, followed it to good effects, but want to know more about the details of how it works, however a search gives me no answers.
In short I am wondering: When mounting apps in Express, what parts of the apps are shared and what parts are not?
Some examples to clarify my question:
app.js:
app.use(express.bodyParser());
app.use(loginApi); //loginApi is an express app
app.listen(3000);
This example works. But if I place the app.use(loginApi) before app.use(express.bodyParser()); , the body parser will not be available in the loginApi subapp. Why is that?
Another example:
submodule.js
var app = module.exports = require('express')();
app.all('*', function(req, res, next){
console.log('nifty middleware');
next();
});
app.js
app.get('/funtimes', fn);
app.use(submodule);
app.listen(3000);
Now in this example, If I understand it correctly, the /funtimes route will not be affected by the submodule middleware for all routes. But what about the rest of the routes of app.js ? Will they be affected? And what if I add another module, will it be affected?
if I place the app.use(loginApi) before app.use(express.bodyParser()); , the body parser will not be available in the loginApi subapp. Why is that?
That's because of the way Express handles requests. Any incoming request starts at the top of the middleware stack, starting with app.use() stack.
Middleware are simply functions that have the function signature function(req, res, next) which either call next() if they want to hand off the request to subsequent functions, or send a response themselves. You define a 'middleware chain' of a bunch of these functions (many are provided by express, like express.logger() and express.compress().)
So in the following scenario:
app.use(express.bodyParser());
var loginApi = require('./api/index.js')
app.use(loginApi);
app.use(app.router);
then an incoming request will first hit app.use(express.bodyParser()), parsing req.body. Then that function calls its internal next(), passing it to the next function in the middleware chain (app.use(loginApi)). The loginApi app has its own middleware chain, but the requests already have req.body set from the outer app. If the loginApi doesn't send a response, the request will continue to app.use(app.router) and at that point the requests will go to the routing functions you set up in your outer app.
So the answer is: A mounted app will have the middleware functions shared, which are placed before the line app.use(loginApi)
Middleware runs in order (until one of the middlewares doesn't call next()).
If you use() your mounted app before use()ing bodyParser, the entire sub-app will run before bodyParser adds its properties.
What you're asking about is middleware. This confused me for a while. Middleware are the functions that run in order to take a request in and serve back a response. app.use() takes a function as its only argument. That function manipulates the request in a consistent way.
app.use is a lot like app.all("*").
The order matters. For example, you might want to run a validator before serving the response.
One thing I learned recently is that you can pass an array of middleware functions to a route. For example
app.get("/whatever",[
function(req,res,next}{
...validation...
next();
},
function(req,res) {
...actions....
res.send(200);
}
]);
The next callback tells express to run the next function in the middleware. Middleware can also modify the request object. This is used a lot in authentication. For example, you'll see req.user getting defined from the database so in later middleware you'll be able to refer to properties of the user. But, it can also be used for a ton of other stuff.
I am new to node.js and express and have been experimenting with them for a while. Now I am confused with the design of the express framework related to parsing the request body.
From the official guide of express:
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(logErrors);
app.use(clientErrorHandler);
app.use(errorHandler);
After setting up all the middleware, then we add the route that we want to handle:
app.post('/test', function(req, res){
//do something with req.body
});
The problem with this approach is that all request body will be parsed first before the route validity is checked. It seems very inefficient to parse the body of invalid requests. And even more, if we enable the upload processing:
app.use(express.bodyParser({uploadDir: '/temp_dir'}));
Any client can bombard the server by uploading any files (by sending request to ANY route/path!!), all which will be processed and kept in the '/temp_dir'. I can't believe that this default method is being widely promoted!
We can of course use the bodyParser function when defining the route:
app.post('/test1', bodyParser, routeHandler1);
app.post('/test2', bodyParser, routeHandler2);
or even perhaps parse the body in each function that handle the route. However, this is tedious to do.
Is there any better way to use express.bodyParser for all valid (defined) routes only, and to use the file upload handling capability only on selected routes, without having a lot of code repetitions?
Your second method is fine. Remember you can also pass arrays of middleware functions to app.post, app.get and friends. So you can define an array called uploadMiddleware with your things that handle POST bodies, uploads, etc, and use that.
app.post('/test1', uploadMiddleware, routeHandler1);
The examples are for beginners. Beginner code to help you get the damn thing working on day 1 and production code that is efficient and secure are often very different. You make a certainly valid point about not accepting uploads to arbitrary paths. As to parsing all request bodies being 'very inefficient', that depends on the ratio of invalid/attack POST requests to legitimate requests that are sent to your application. The average background radiation of attack probe requests is probably not enough to worry about until your site starts to get popular.
Also here's a blog post with further details of the security considerations of bodyParser.