Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / security

Building Your First MEAN Stack Web Application – Part 2

2.33/5 (2 votes)
13 Mar 2017CPOL11 min read 8.8K  
Part-2 in the series of developing a basic Web Application using MEAN Stack

This is part 2 in the series of developing a basic Web Application using MEAN Stack. MEAN is actually a combination of multiple language platforms to create applications. It is a shorthand wherein M stands for MongoDb, E stands for Express, A stands for Angular.js and N stands for Node.js.

In the previous part of this MEAN Stack Application, we covered the following things:

  • Environment Setup for MEAN Web Development
  • Routes for MEAN Stack Application
  • User Registration Process

Alright so far so good, now let's start with validation and DAO part of register module.

In routes folder, where we have added method to render view for register, in the same file, we will be adding code, for what will happen when there will be a post request.

JavaScript
router.post("/register", function(req,res){
   
   var name = req.body.name;
   var userName = req.body.username;
   var password = req.body.password;
   var email = req.body.email;   
);

As we can see now, we have added post on "/register" that is coming from UI. Now to get values from request, the below syntax is used:

req.body.<fieldname>

So as we did, we received all four values from our view and now it's up to the controller to validate the values and store them in database.

Let's first validate these values:

To validate, we have already added validator module in our code main file that is main.js, now all we need to do is to validate the data. Syntax to validate data is:

JavaScript
req.checkBody(<Field_Name>," Error_Message").<Validator_Function>;

So in the syntax above, Field_Name will be the name of field that needs to be validated, Error_message will the error message that we need to display in case validation fails, Validator_Function is the function that will be specific to data object, for example, for name we will check with NotEmpty(), whereas for email we will check with NotEmpty() as well as with isEmail() methods. Let's now write code to validate data. In the same method that is written above, we will add some validation part now. Below is the code that will validate the data.

JavaScript
req.checkBody("name"," Name is required ").notEmpty();
req.checkBody("email"," Email is required ").notEmpty();
req.checkBody("email"," Invalid email id").isEmail();
req.checkBody("username"," Username is required ").notEmpty();
req.checkBody("password"," Password is required ").notEmpty();

Now we have our validation code in place. Now, the question arises as to how these will work, how these error messages will be displayed to the client, who will be responsible for this and so on and so forth. So our next task is to get all the errors and direct to register view. Let's do this:

JavaScript
var error = req.validationErrors();

The above piece of code will collect all the errors if any in the validation part. Now our task is to use this and forward to the client. Let's write a small piece of code for this as well.

JavaScript
if(error){
   res.render('register',{error:error});
}

So if there is any error, render the register view with errors in it. Before we restart the server and test, we need to add some piece of code in view part as well.

JavaScript
{{#if error}}
   {{#each error}}
      <div class="alert alert-danger">{{msg}}</div>
   {{/each}}
{{/if}}

So this is the code that we will be adding to our register view. Traverse through each error object and display it.

Now we are good to go with the testing part of register view. Let's restart the server and see if we got all that we have expected or not. So in the example snippet below, I have added email, username, password and not name, let's submit now and see what happens.

MEAN Stack Example

Upon submitting this page, what we will get is:

MEAN Web Application Validation

And the same validation will work for all data fields. So we are good with the validation part of our register module. Now when validation is working fine, we have data object, so we will be happy to store the data in database and register user to our application. In the next section, we will be talking about storing data to the database.

So now when everything goes fine and there is no validation error in our page, we will like to store data in the database and register user to use our application. So what we will do is create a user object and populate this with the values we got from request and pass to dao layer for persistence.

JavaScript
var user = new userObject({
   name:name,
   email:email,
   username:userName,
   password:password
});
userObject.createUser(user, function(error,user){
   if(error) throw error;
});

req.flash('success_message', 'Resisteted Successfully');

res.redirect('/users/login');

Here, we have createUser method that we will write in dao layer part, next thing is, if everything goes fine and there is no error, then we will notify user with success message, which will state that registration is successful and the last thing we will do is to redirect the user to login page so that user can login, with the credentials. Let's now move to dao layer, where we will write createUser function.

Remember when we talked about the different folders, we talked about models folder that is responsible for data interaction part with database. So we will start writing our code in user.js which is DAO layer for our application. Here, we will be creating the createUser function.

JavaScript
module.exports.createUser = function(userObject,callback){
   userObject.save(callback);
}

This piece of code will store our data in database. Let's test this, we need to start the server, and in browser, go to localhost:8777, since our app is listening at port number 8777.

On register page, we have filled the information and we are going to post the request. Let's see if our code works fine.

Register New User

Upon post, what we get is the below screen. So our registration code is working fine and we have redirected to the sign-in page.

MEAN Stack Tutorial

Great!! Isn't it, we have successfully registered user Ahmad. Let's check in our db for the values.

MongoDB Query

So we have all the values stored that we have passed from UI. But there is one glitch, if you can at the db data, we are storing password in plain text. By doing so, we are creating a security loophole in our application. It should not happen right, one can take dump of our database and easily hack our system. What to do now..

Calm down, here crypto comes to rescue us. So it's a thumb rule that we should not and we must not store password as plain text in database. So what we will do is encrypt the password and then save to database.

First, we need to have this module with our application, let's add this:

JavaScript
var crypto = require('crypto');

Now we are all set to use crypto capability and functions. So what we are going to do is to encrypt the password using sha512 algorithm and persist to database. Lets write code for this:

JavaScript
var generateHash = function(password){
    var hash = crypto.createHmac('sha512', 'Secret'); /** Hashing algorithm sha512 */
    hash.update(password);
    var value = hash.digest('hex');
    return value;
};

The code block above will generate hash for the given data using sha512 algorithm. So we are going to use this function and encrypt our password and try to persist.

In createUser function, we will call this generateHash function. Let's amend the createUser method now:

JavaScript
module.exports.createUser = function(userObject,callback){
   var hash = generateHash(userObject.password);
   userObject.password  = hash.passwordHash;
   userObject.save(callback);
}

And we are all set to go and test our application. Before proceeding, we are going to remove the data from database, since it was incorrect. Let's remove data and restart the server.

MongoDB Remove User

Then, with the same dataset, we are going to register user, So we are not repeating the same screens as above, assuming that we have inserted the same data as above. Let's check in database now:

Query MongoDB

So if you can see, now we have encrypted password in our database, and this completes the registration module.

Let's start writing code for login module.

So we will use something called passport for login module. First, we need to import passport and passport-local in our code so we can use the capabilities of this.

JavaScript
var passportObject = require("passport");
var passportLocal = require("passport-local").Strategy;

Here, we have created two refs, one for passport and another for Passport-local. Since we will be using passport local Strategy in our login module.

Passport overview from http://passportjs.org/docs

Passport is authentication middleware for Node. It is designed to serve a singular purpose: authenticate requests. When writing modules, encapsulation is a virtue, so Passport delegates all other functionality to the application. This separation of concerns keeps code clean and maintainable, and makes Passport extremely easy to integrate into an application.
In modern web applications, authentication can take a variety of forms. Traditionally, users log in by providing a username and password. With the rise of social networking, single sign-on using an OAuth provider such as Facebook or Twitter has become a popular authentication method. Services that expose an API often require token-based credentials to protect access.
Passport recognizes that each application has unique authentication requirements. Authentication mechanisms, known as strategies, are packaged as individual modules. Applications can choose which strategies to employ, without creating unnecessary dependencies.

Once we are setup with passport objects, like register, we will write post handling for login. Let's write the code for the same:

JavaScript
router.post('/login',
    passportObject.authenticate('local', 
    {successRedirectUrl:"/",failureRedirectUrl:"/users/login", failureFlash :true}),
    function(req, res) {
      res.redirect("/");
});

So in the code above, we are using authenticate method of passport, which has a parameter as "local", since we are using local database, other parameters are success and failure URLs and a Boolean flag as do we need to display the flash messages or not.

Now passport local will come into play and in the next section, we will be talking about fetching values from database and authenticating user.

JavaScript
passportObject.use(new passportLocal(
    function(username, password, done) {
       //
      userObject.findByUsername(username, function(error, foundUser){
         if(error) throw error;
         if(!foundUser){
            done(null, false, {msg : 'Auhentication failed, Invalid Username !! '});
         }

         //Validate Password
         userObject.validatePassword(password, foundUser.password, function(error,found){
            if(found) return done(null, foundUser)
            else done(null, false, {msg : 'Auhentication failed, Invalid Password  !! '});
         })
      });
      //
    }
));

So the first line of our code is basic syntax of passport object which tells passport which strategy has been used and accordingly, the object will be created, like in our example, we are using passport-local strategy, so the object we have created is PassportLocal. It was a basic fix syntax, and the next line as well, which provides username and password from vie. Our work starts from the next line, so we have username and password data in our router file. Now what we will do is we will make a call to the database and try to get the user based on username. Remember when we have created schema, we kept username as index.

Traverse to user.js file that is dao layer of our application. In this file, we will be creating a function to fetch user data from database.

JavaScript
module.exports.findByUsername = function(username, callback){
    User.findOne({username:username},callback);
}

So we made a call to database with query username. It will return the user data for the usename we have passed in the query, and the same function is called from our router. Now, the below piece of code:

JavaScript
function(error, foundUser){
   if(error) throw error;
   if(!foundUser){
      done(null, false, {msg : 'Auhentication failed, Invalid Username !! '});
}

That is in the router post method for login, will check if there is any error or not, if there is any error, error will be displayed on page and it will be redirected to the URL that we have provided. If there is no data in foundUser, (foundUser is just a parameter name, that we got as callback from dao layer) i.e., there is no data present in database corresponding to the username. So if there is no data, we will throw an error message as 'Authenticaion failed, Invalid Username!!'. If there is data present in database corresponding to the username, the next step is to validate password. So again, we will go to dao layer and write a method that will have code to validate password.

One more interesting thing here to notice, if you can remember, we have saved our password in encrypted from using sha512 crypto algorithm. Now the glitch is that we cannot decrypt the password, once encrypted, it's encrypted, so how will we compare and check the passwords now and how will we authenticate the user. To overcome this, what we will do is we will encrypt the password with the same sha512 algorithm and then compare both the passwords. Let's write code for this:

JavaScript
module.exports.validatePassword = function(password, foundPasswordHash, callback){
 
   var hash = generateHash(password);

    var pwHash  = hash.passwordHash;

    if(pwHash==foundPasswordHash){
      callback(null,true);
   }else {
       callback(null, false);
   }
}

So the most important part is to generateHash here, we have reused the same method that we have created at the time of registration for hashing. If both hashes are the same, then we will be passing true to router and if not, then we will pass false.

One more thing that we need to do is, when user logs in, we will display welcome message with his name, so we need user's name on view part as well. Also once user is logged in, he should not be able to see the Register and Login links. And when user is logged out, he should not see the Home and Logout link.

To achieve this, we need to modify our main.js file and add local for user as well. Let's add this:

JavaScript
res.locals.user = req.user || null;

in app.use method, where we are setting flash messages, we will add this line. Now at view part, we will use this local to show hide links.

JavaScript
{{#if user}}
     <li role="presentation"><a href="/">Home</a></li>
     <li role="presentation"><a href="/users/logout">Logout</a></li>
 {{else}}
     <li role="presentation"><a href="/users/login">Login</a></li>
     <li role="presentation"><a href="/users/register">Register</a></li>
{{/if}}

So we will add this check in our layout file. The code says that if user is null that we are setting in main.js then user is not logged in and he is good to go with Register and login links.

Note: In order to keep things simple, we didn’t beautify the application but that can be easily done using bootstrap framework. You can find all about bootstrap framework here.

In index view, we are going to use the user object to fetch user's name to display welcome message:

JavaScript
<h4 class="text-muted">Welcome {{user.name}} to Online bookstore, 
Below is the list of books you recently purchased.</h4>

Let's test with putting it all together. For that, we need to restart the server again. Let's restart and test.

Web App Login

So we are trying to login user Ahmad, let's see if Ahmad can login to our system:

MEAN Stack Book Store Example

Alright, so Ahmad is successfully logged in and he can see the recent orders he placed with our online book store.

Last thing is to check logout functionality. Let's check:

MEAN Stack App Example

Alright, everyting is working fine, well and good. So it completes this tutorial for MEAN stack user registration and login module.

More MEAN Stack and Related Tutorials

The post Building your first MEAN Stack Web Application – Part2 appeared first on Web Development Tutorial.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)