Thursday, November 3, 2016

Tutorial 3: ExpressJS – Using 3rd Party Middleware Stack

Tutorial 3: Express Module – 
Understanding routing using 3rd Party Middleware

Tutorial 1: NodeJS: An Asynchronous World
Tutorial 2: Express: Middleware or more...
Tutorial 3: Understanding Routing in Express
Tutorial 4: Develop a Static File Server
Tutorial 5: Using HTTPS with Express
Tutorial 6: Develop a JSON API server
Tutorial 7: Use Templates and Views with Express
Tutorial 8: Integrating MongoDB
Tutorial 9: Testing Express Applications
Tutorial 10: Securing Express



ExpressJS based applications can use numerous third party middleware modules available free or commercially. When a request enters expressJS based node application, the request goes through the middleware stack from top to botton unless it meets an error or a response. Thus expressJS routers help splitting up applcation into manageable independent mini applications.

A few commonly used middlewares are listed below:

express-session: To implement sessions in express, this module comes handy. It supports two main ways to implement session i.e. cookies and session-store at the backend.

cookie-parser: Cookie is a small piece of data sent from a website and stored on the user's computer by the user's web browser while the user is browsing. In general developers use it along with express-session. The cookie-parser middleware enables signed cookies which can be referenced by other middleware components, using an optional secret attribute.

useragent : Sometimes you want to serve different web pages to different browsers or you want to limit serving your application to browsers of minimum version, useragent module is very helpful.

body-parser: It  parses incoming browser's request in a middleware before your handlers. Useful in form-handling.

morgan: It is a http logger. By default it logs to console or you can redirect to file stream.




Let's try to build a simple web application using these third party middleware stack. This web application simply displays a form asking for user's first name and last name.

Let us install these modules using the following command in a bash shell.

$ npm install express-session cookie-parser useragent body-parser morgan

The node-module sub-directory will show the listing of modules installed. 

Tutorial 3: ExpressJS –  Using 3rd Party Middleware Stack

Here is the complete code snippet. The web application loads the 3rd party modules and use these in expressJS. The web application starts a session showing a simple form asking user's first name and last name. On submitting the application it displays the name values entered and also stores 'first name' as server side session variable. If a user tries to access 'URL/user' after the form submission, it displays the user name. Otherwise it redirects to main page.



 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
var express = require('express');
var app = express();

var bodyParser = require('body-parser');
var morgan = require('morgan');
var cookieParser = require('cookie-parser');
var expressSession = require('express-session');
var useragent = require('useragent');


app.use(morgan('combined'));
app.use(cookieParser());

// create application/x-www-form-urlencoded parser 
var urlencodedParser = bodyParser.urlencoded({ extended: false })
app.use(expressSession({secret:'secret_token_here', saveUninitialized: true,
resave: true}));

app.get('/', function(req, res){
 var isAndroid = useragent.is(req.headers['user-agent']).android;
 if (isAndroid) {
  res.end('Android support not available at present');
 } else {
  res.cookie('welcome_cookie', 'welcome', {maxAge : 9999});
  res.sendFile(__dirname + '/' + 'index.htm');  
 }
});

app.post('/login', urlencodedParser, function(req, res){
 if (!req.body)
  return res.sendStatus(400);
 res.write('welcome');
 // prepare response in JSON format
 response = {
  firstname : req.body.fname,
  lastname  : req.body.lname
 }
 sess=req.session;
 sess.username = req.body.fname;
 res.end(JSON.stringify(response));
});

app.get('/user', function(req, res) {
 var sess = req.session;
 if (!sess.username)
  res.redirect('/');
 else {
  res.end('welcome ' + sess.username);
 }
});

var server = app.listen(8080, function(){
 var host = server.address().address;
 var port = server.address().port;
 console.log("Server listening at http://%s.%s", host,port);
});

Let us go through the code line by line.
See the first 10 lines.

var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var morgan = require('morgan');
var cookieParser = require('cookie-parser');
var expressSession = require('express-session');
var useragent = require('useragent');


The first 10 lines loads the respective modules.

See the line 11 i.e.
  app.use(morgan('combined'));

It asks expressJS to user morgan module which a http logger. The option 'combined' generates standard apache like web server log output. You can check the log out displayed on the shell

Tutorial 3: ExpressJS –  Using 3rd Party Middleware Stack

The line 12 i.e.
  app.use(cookieParser());

assigns codeparser to expressJS module to set secure session cookie, as it does in line 16.

  app.use(expressSession({secret:'secret_token_here', saveUninitialized: true, resave: true})); 

The line number 15,

var urlencodedParser = bodyParser.urlencoded({ extended: false }) 

creates a url-encoded parser to parse the name fields send by a web form.

See the code lines 18 to 26

app.get('/', function(req, res){ 

var isAndroid = useragent.is(req.headers['user-agent']).android;
 if (isAndroid) {
  res.end('Android support not available at present');
 } else {
  res.cookie('welcome_cookie', 'welcome', {maxAge : 9999});
  res.sendFile(__dirname + '/' + 'index.htm');  
 }
});


The above code handles get request to serve the root or main page. It first checks the user agent of the requesting browser. If it is android-based user then it simply sends a message that the current application is not supported on android platform. It is one of the way you can use user-agent module in your web application.

Tutorial 3: ExpressJS –  Using 3rd Party Middleware Stack

For other browser version it serves index.htm file by reading it from current directory. The index.htm renders a simple web form.

Tutorial 3: ExpressJS –  Using 3rd Party Middleware Stack

Check the Cookies tab under Chrome Developers-> Network -> Click on localhost. You can see the web application sets a secure cookie. It also sets a local cookie which does not persist.


Tutorial 3: ExpressJS –  Using 3rd Party Middleware Stack


Line no. 29 to 41 implements the user form response.


app.post('/login', urlencodedParser, function(req, res){
        if (!req.body)
                return res.sendStatus(400);
        res.write('welcome');
        // prepare response in JSON format
        response = {
                firstname : req.body.fname,
                lastname  : req.body.lname
        }
        sess=req.session;
        sess.username = req.body.fname;
        res.end(JSON.stringify(response));
});


It checks if req.body, which holds the parameters sent by POST request, is empty then sends error 404 response. Otherwise reads the fname and lname field values and prepares a response. It also stores the user's firstname as server session variable (line no. 38 and 39).
See code 43 to 50.


app.get('/user', function(req, res) {
 var sess = req.session;
 if (!sess.username)
  res.redirect('/');
 else {
  res.end('welcome ' + sess.username);
 }
});


It implements a /user GET api. It checks if server session variable 'username' is set, it displays the welcome message else it redirects to main page. This example uses Memorystore, an in built storage to store session variables. However for production purposes, it is insufficient and you should use third party stores like redis, express-sessions etc.

Finally the code lines from 52-56 creates web server which listens at port 8080.


var server = app.listen(8080, function(){
 var host = server.address().address;
 var port = server.address().port;
 console.log("Server listening at http://%s.%s", host,port);
});


I hope this post provides you an overview how middle wares can be used with expressJS module to develop a web based application.

In the next tutorial, we'll discuss how expressJS has in-built support to serve web static content.

No comments: