https://www.learn2crack.com/2014/04/android-login-registration-nodejs-server.html



In this series of tutorials we are going to see how to develop a complete android login registration system with Node.js platform and MongoDB document oriented database.

What we will do ?

-> Setup Node.js in Windows and Ubuntu.
-> Registration, Login in Android and Store Data in MongoDB.
-> Reset Password with Email.
-> User Profile page with Gravatar.
-> SHA512 encryption for Passwords.

Why Node.js ?

-> Hottest new technology.
-> Node.js is JavaScript running on the Server.
-> Runs on Chrome V8 JavaScript engine.
-> Its Non blocking and Event driven.
-> Faster than PHP.
-> Does not need additional Server stack such as Apache or NGINX, It has inbuilt http module.
-> JavaScript is easier to learn.
-> Inbuilt Package Manager to install modules.
-> JSON is easier to Use.

Android Login Registration System with Node.js and MongoDB

Node.JS vs Other

Why MongoDB ?

-> NoSQL database.
-> Data is stored in Objects rather than tables in MySQL.
-> Easier to work with Node.js.
-> Stores data in JSON format.

Our tutorial has two major parts

1. Setting up Server with Node.js and MongoDB
2. Develop client side Android application to interact with MongoDB.

Setting up Server Side

Prerequisites

See the following tutorial to setup Node.js and MongoDB in your Linux or Windows machines.

How to Setup Node.js and MongoDB in Ubuntu and Windows

Use the GUI client Robomongo to access MongoDB. It is available for all the platforms.

Download Complete Project

Creating the project

-> Create a MongoDB database named node-android.
-> Create a directory named node-android and change to the directory.
-> Create package.json file and include the following dependencies.

package.json

{
	"name": "node-android",
	"version": "0.0.1",
	"main": "app.js",
	"dependencies": {
		"express" : "~4.0.0",
		"mongoose" : "~3.8.8",
		"csprng" : "~0.1.1",
		"connect": "~2.14.4",
		"nodemailer":"~0.6.3",
		"crypto":"~0.0.3",
		"gravatar":"~1.0.6"
  }
}

-> Now enter npm install in linux terminal or windows command prompt.
-> Now all the packages begins downloading and it is available in the directory node_modules.

Android Login Registration System with Node.js and MongoDB Android Login Registration System with Node.js and MongoDB

Lets see why we use these packages.

express:

express is a Node.js framework. It is used to simplify some of the basic tasks.

mongoose:

mongoose is a Node.js module which is used to interact easily with MongoDB databases.

csprng:

cspring is used to generate random strings which is used as salt which is used to generate more secure hashed password.

connect:

Connect is a express middleware which is used to parse form data, and to use logger which prints the request in the terminal.

Android Login Registration System with Node.js and MongoDB

Connect Logger

nodemailer:

nodemailer is used to send mail using SMTP for resetting the user password.

crypto:

crypto is a Node.js module used to generate SHA512 hashes.

gravatar:

This simple Node.js module is used to get the Gravatar Image URL of the user.

Here is the diagram representing Our Project structure in the Server.

Android Login Registration System with Node.js and MongoDB

Creating app.js

Create a file named app.js in the root of the node-android folder. It is the main file which makes our server up and run. Here our application runs on the port 8080 in localhost.

app.js

/**
 * Module dependencies.
 */
var express  = require('express');
var connect = require('connect');
var app      = express();
var port     = process.env.PORT || 8080;

// Configuration
app.use(express.static(__dirname + '/public'));
app.use(connect.logger('dev'));
app.use(connect.json());
app.use(connect.urlencoded());

// Routes

require('./routes/routes.js')(app);

app.listen(port);

console.log('The App runs on port ' + port);

 

Setting up routes with routes.js

Our routes.js file handles all the HTTP requests such as GET, POST. We need to create our own routes to handle login, register, change password events, forgot password events. The GET requests are defined by app.get nethod and POST are defined by app.post methods. The functions to handle login, registration and change password are login.js, register.js, chgpass.js which will be placed in config directory inside the node_modules directory. We are importing the defined function using require(”). Login module is imported using require(‘config/login’) . config is the directory of the login module.

For the requests to the URL we would call the function which is predefined to perform the operation. For example for register operation we would post the email and password parameters to the URL http://127.0.0.1:8080/register from our Android Application and Node.js handles the register operation by calling the register function and returns the result back to the user in JSON format.

app.post('/register',function(req,res){
var email = req.body.email; // Getting the parameters
var password = req.body.password;

register.useremail(email,password,function (found) { //Register function to perform register event
console.log(found); // Prints the results in Console.(Optional)
res.json(found); // Returns the result back to user in JSON format
});
});

Similar to register we need to define our routes for other operations. Routes which are not defined are send with 404 error. The complete routes.js which has routes to all the operations. Our routes.js file is placed in the routes directory.

routes.js

var chgpass = require('config/chgpass');
var register = require('config/register');
var login = require('config/login');


module.exports = function(app) {



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

		res.end("Node-Android-Project");
	});


	app.post('/login',function(req,res){
		var email = req.body.email;
        	var password = req.body.password;

		login.login(email,password,function (found) {
			console.log(found);
			res.json(found);
	});
	});


	app.post('/register',function(req,res){
		var email = req.body.email;
        	var password = req.body.password;

		register.register(email,password,function (found) {
			console.log(found);
			res.json(found);
	});
	});


	app.post('/api/chgpass', function(req, res) {
		var id = req.body.id;
                var opass = req.body.oldpass;
		var npass = req.body.newpass;

		chgpass.cpass(id,opass,npass,function(found){
			console.log(found);
			res.json(found);
	});
	});


	app.post('/api/resetpass', function(req, res) {

		var email = req.body.email;

		chgpass.respass_init(email,function(found){
			console.log(found);
			res.json(found);
	});
	});


	app.post('/api/resetpass/chg', function(req, res) {

		var email = req.body.email;
		var code = req.body.code;
		var npass = req.body.newpass;

		chgpass.respass_chg(email,code,npass,function(found){
			console.log(found);
			res.json(found);
	});
	});


};

Defining MongoDB database Schema

Our schema defines the database stucture. All our data are of String type. It is defined in JSON format. Email is defined such as “email : String”. Connection with MongoDB is established using mongoose.connect(). The connection url is “mongodb://localhost:27017/node-android”. 27017 is the port number of MongoDB. node-android is our Database name. You can also add username and password to your database to make it more secure. The user schema is defined globally in models.js so that we can use easily in all our modules.

models.js

var mongoose = require('mongoose');

var Schema = mongoose.Schema;

var userSchema = mongoose.Schema({
	token : String,
	email: String,
	hashed_password: String,
	salt : String,
	temp_str:String
});

mongoose.connect('mongodb://localhost:27017/node-android');
module.exports = mongoose.model('users', userSchema);

Defining register module with register.js

The register module has a global register function which has parameters email, password and a callback. Initially we check whether the Email is valid or not, if not alerts the user. Next is to check the password strengh. The password length should be more than 4, it should contain caps, numbers and a special character. You can change it according to your needs. We are encrypting our data by using salt- a random string added to password and then the password is hashed using SHA512 encryption and then it is stored in the database. A token is also stored which is used to change password. It is very hard to hack these kind of passwords with salt. If the user is sucessfully registered response message is sent as json format.

register.js

var crypto = require('crypto');
var rand = require('csprng');
var mongoose = require('mongoose');
var user = require('config/models');



exports.register = function(email,password,callback) {

var x = email;
if(!(x.indexOf("@")=x.length)){
if (password.match(/([a-z].*[A-Z])|([A-Z].*[a-z])/) && password.length > 4 && password.match(/[0-9]/) && password.match(/.[!,@,#,$,%,^,&,*,?,_,~]/)) {

var temp =rand(160, 36);
var newpass = temp + password;
var token = crypto.createHash('sha512').update(email +rand).digest("hex");
var hashed_password = crypto.createHash('sha512').update(newpass).digest("hex");

var newuser = new user({
	token: token,
	email: email,
	hashed_password: hashed_password,
	salt :temp });

user.find({email: email},function(err,users){

var len = users.length;

if(len == 0){
 	newuser.save(function (err) {

	callback({'response':"Sucessfully Registered"});

});
}else{

	callback({'response':"Email already Registered"});

}});}else{

	callback({'response':"Password Weak"});

}}else{

	callback({'response':"Email Not Valid"});

}
}

Defining login module with login.js

In this module login function is defined which takes email, password parameters with callback. The password from the user is added with salt from the database and hashed. The generated hash and hash from database are compared. If its equal return the token to the user with gravatar image url of the users email address in JSON format. If not alert messages are returned.

login.js

var crypto = require('crypto');
var rand = require('csprng');
var mongoose = require('mongoose');
var gravatar = require('gravatar');
var user = require('config/models');

exports.login = function(email,password,callback) {

user.find({email: email},function(err,users){

if(users.length != 0){

var temp = users[0].salt;
var hash_db = users[0].hashed_password;
var id = users[0].token;
var newpass = temp + password;
var hashed_password = crypto.createHash('sha512').update(newpass).digest("hex");
var grav_url = gravatar.url(email, {s: '200', r: 'pg', d: '404'});
if(hash_db == hashed_password){

callback({'response':"Login Sucess",'res':true,'token':id,'grav':grav_url});

}else{

callback({'response':"Invalid Password",'res':false});

}
}else {

callback({'response':"User not exist",'res':false});

}
});
}

Defining chgpass module with chgpass.js

This module has the functions to change the user password in profile page and reset the password if the user has forgotten his/her password. The cpass function defined is used to change the password in profile page by getting old password, new password and token as parameters. If the old password and the password stored in the database match new password is set or error message is returned.

Next function is the respass_init function which is used to send a random string to the User’s email address to reset the password. We use nodemailer module to send mail using SMTP.

Next function is the respass_chg function which gets the code which is sent as email, new password, email as parameters. If the code matches with the one which is sent new password is set or error is displayed.

chgpass.js

var crypto = require('crypto');
var rand = require('csprng');
var mongoose = require('mongoose');
var nodemailer = require('nodemailer');
var user = require('config/models');

var smtpTransport = nodemailer.createTransport("SMTP",{
    auth: {
        user: "user@gmail.com",
        pass: "********"
    	}
});


exports.cpass = function(id,opass,npass,callback) {

var temp1 =rand(160, 36);
var newpass1 = temp1 + npass;
var hashed_passwordn = crypto.createHash('sha512').update(newpass1).digest("hex");

user.find({token: id},function(err,users){

if(users.length != 0){

var temp = users[0].salt;
var hash_db = users[0].hashed_password;
var newpass = temp + opass;
var hashed_password = crypto.createHash('sha512').update(newpass).digest("hex");


if(hash_db == hashed_password){
if (npass.match(/([a-z].*[A-Z])|([A-Z].*[a-z])/) && npass.length > 4 && npass.match(/[0-9]/) && npass.match(/.[!,@,#,$,%,^,&,*,?,_,~]/)) {

user.findOne({ token: id }, function (err, doc){
  doc.hashed_password = hashed_passwordn;
  doc.salt = temp1;
  doc.save();

callback({'response':"Password Sucessfully Changed",'res':true});

});
}else{

callback({'response':"New Password is Weak. Try a Strong Password !",'res':false});

}
}else{

callback({'response':"Passwords do not match. Try Again !",'res':false});

}
}else{

callback({'response':"Error while changing password",'res':false});

}

});
}

exports.respass_init = function(email,callback) {

var temp =rand(24, 24);
user.find({email: email},function(err,users){

if(users.length != 0){


user.findOne({ email: email }, function (err, doc){
  doc.temp_str= temp;
  doc.save();

var mailOptions = {
    from: "Raj Amal  <raj.amalw@gmail.com>",
    to: email,
    subject: "Reset Password ",
    text: "Hello "+email+".  Code to reset your Password is "+temp+".nnRegards,nRaj Amal,nLearn2Crack Team.",

}

smtpTransport.sendMail(mailOptions, function(error, response){
    if(error){

callback({'response':"Error While Resetting password. Try Again !",'res':false});

    }else{

callback({'response':"Check your Email and enter the verification code to reset your Password.",'res':true});

    }
});
});
}else{

callback({'response':"Email Does not Exists.",'res':false});

}
});
}

exports.respass_chg = function(email,code,npass,callback) {


user.find({email: email},function(err,users){

if(users.length != 0){

var temp = users[0].temp_str;
var temp1 =rand(160, 36);
var newpass1 = temp1 + npass;
var hashed_password = crypto.createHash('sha512').update(newpass1).digest("hex");

if(temp == code){
if (npass.match(/([a-z].*[A-Z])|([A-Z].*[a-z])/) && npass.length > 4 && npass.match(/[0-9]/) && npass.match(/.[!,@,#,$,%,^,&,*,?,_,~]/)) {
user.findOne({ email: email }, function (err, doc){
  doc.hashed_password= hashed_password;
  doc.salt = temp1;
  doc.temp_str = "";
  doc.save();

callback({'response':"Password Sucessfully Changed",'res':true});

});}else{

callback({'response':"New Password is Weak. Try a Strong Password !",'res':false});

}
}else{

callback({'response':"Code does not match. Try Again !",'res':false});

}
}else{

callback({'response':"Error",'res':true});

}
});
}

Now we have set the server part. Now switch to the root of our project and enter the command node app. Now our app will be running on the port 8080 in localhost. Open the browser and hit 127.0.0.1:8080 you will see the message “Node-Android-Project” in your browser.

Next proceed to the Client part- Developing Android Application.