Authentication

this is the process of confirming some person's identity

 

HOW? there are many ways including some very popular 3rd party standard you can get software for like OAuth. There are services like Google login etc that can also be used

 

WHAT ARE WE DOING HERE? -- showing some simple code that:

1) Sing UP: a capability that lets the user specify a unique ID and a password. This data is read from a signup.ejs form data and compares to what has been done before..... This information is stored in the session --you would want in reality a BETTER SOLUTION --like using a database

2) Log IN: if the user has specified thier userid and password, they can bring up /login (login.ejs) form to log in. It compares the userid with the session information and if present lets them login

3) Protected Page: the user can access the /protectedpage url if the user has logged in. If not they are given an error message.

STEP 0: follow the steps to create an NodeJS Express application.

 

 

STEP 1: as using sessions and cookies must install modules

GO TO application directory and type

npm install --save cookie-parser

 

npm install --save express-session

 

STEP 2: create various forms/pages: signup.ejs, login.ejs, protected_page.ejs and put in views/pages directory

signup.ejs

<!DOCTYPE html>
<html>
<head>
 <title>Signup Form</title> 
 </head>
<body>
Sign UP Form <br><br>
<form action="/login", method="POST")
   <div>
   <label> UserID</label>
   <input type="text" name="id" value="enter id"> 
   <br/>
   <label> Password:</label>
   <input type="text" name="password"  value="enter password"> 
   <input type="submit" value="Sign Up"> 
   </div>
</form>
</body>
</html>

 

 

login.ejs

<!DOCTYPE html>
<html>
<head>
 Login Form
 </head>
<body>
Login Form <br><br>
<form action="/login", method="POST")
   <div>
   <label> UserID</label>
   <input type="text" name="id" value="enter id"> 
   <br/>
   <label> Password:</label>
   <input type="text" name="password"  value="enter password"> 
   <input type="submit" value="Log in"> 
   d</div>
</form>
</body>
</html>

protected_page.ejs --grabs varible id sent to it

<!DOCTYPE html>
<html>
<head>
<title>Protected page</title>
</head>
<body>
 Protected Page <br><br>
 Hey 
   <%= JSON.stringify(id) %>
</body>
</html>

STEP 3: add code to index.js for module requiring, handlers for /login, /signup, /protectedpage and associated functions --

var cool = require('cool-ascii-faces');
var express = require('express');
var app = express();
var pg = require('pg');
var bodyParser = require('body-parser');
var multer = require('multer');
var path = require ('path'); //to work with separtors on any OS including Windows
var session = require('express-session');
var cookieParser = require('cookie-parser');
var upload = multer(); 
 
app.set('port', (process.env.PORT || 5000));
//***************************************************************************
//STEP 1: SPECIFY ANY app.use() cases
//app.use(express.static(__dirname + '/public'));
app.use(express.static(path.join(__dirname + '/public')));
                   
//process any cookie or session info
app.use(cookieParser());
app.use(session({secret: "Your secret key"}));
//if any form data process it through bodyParser
app.use(bodyParser.json()); // for parsing application/json
app.use(bodyParser.urlencoded({ extended: true })); // for parsing application/x-www-form-urlencoded
app.use(upload.array()); // for parsing multipart/form-data
                   
//Before user can access the URI /protected_page DIRECTLY, the 
// user is redirected to /login URI -- 
app.use('/protected_page', function(err, req, res, next){
    console.log(err);
    //User should be authenticated! Redirect him to log in.
    res.redirect('/login');
 });
 
//******************************************************************
//STEP2:   SETUP VIEW ENGINE AND VIEWS LOCATION
// views is directory for all template files
//app.set('views', __dirname + '/views');
app.set('views', path.join(__dirname + '/views'));  //path.join -resolve OS file separators
app.set('view engine', 'ejs');
 
//*******************************************************************
//STEP 3: SETUP HANDLERS FOR VARIOUS URIS

//Handler for URI /db which does a select from the "test_table" given the DATABASE_URL
app.get('/db', function (request, response) {
       pg.connect(process.env.DATABASE_URL, function(err, client, done) {
          client.query('SELECT * FROM test_table', function(err, result) {
             done();
             if (err)
               { console.error(err); response.send("Error " + err); }
             else
               { response.render('pages/db', {results: result.rows} ); }
           });
       });
  });
//Handler for URI / which simply loads index.ejs inside views/pages
app.get('/', function(request, response) {
      response.render('pages/index');
  });
                   
//Handler for URI /nodeMongoDBTest to manipulate MongoDB database
app.get('/nodeMongoDBTest', function(request, response) {
       response.render('pages/nodeMongoDBTest');
   });
//Hander for URI /form to render form.ejs in views/pages
app.get('/form', function(req, res){
     console.log(req.body);
     res.render('pages/form')
  });
//Handler for URI /processForm that has code to simply display some of the request info
// and form data coming from previous form.ejs
app.post('/processForm', function(req, res){
    console.log(req.body);
    var body = JSON.stringify(req.body);
    var params = JSON.stringify(req.params);
    var value_tofield_formdata = req.body.to;
    var value_sayfield_formdata = req.body.say;
    res.send("recieved your request!</br>" + "parameters: " + params + "</br>URL:" + req.url + "<br>body: " +
body + "<br>the -to- form field = " + value_tofield_formdata +
"<br> the -say- form field = " + value_sayfield_formdata); });
//Handler for URI /cool that calls the cool() function from the cool module
app.get('/cool', function(request, response) {
    response.send(cool());
  });
                   
//Handler for URI /times that is a frequency counter and displays count calculated below
app.get('/times', function(request, response) {
    var result = ''
    var times = process.env.TIMES || 5
    for (i=0; i < tim es; i++)
            result += i + ' ';
    response.send(result);
 });
                   
//Handler for GET URI /signup that renders the signup.ejs in views/pages folder
app.get('/signup', function(req, res){
    res.render('pages/signup');
  });
//Handler for POST URI /signup that expects in the req object the data of id and password
//  sent to it.   If not it sends 400 status.  If both are sent then (stupidly--this
//  is a simple example) checks if we have seen id before (in Users[]) and if so tells user
//  to choose another id.   Otherwise, it adds the user id and password to a Users[] array..
var Users = [];
app.post('/signup', function(req, res){
  if(!req.body.id || !req.body.password){
      res.status("400");
      res.send("Invalid details!");
    }
  else{
      Users.filter(function(user){
         if(user.id === req.body.id){
             res.render('signup', {message: "User Already Exists! Login or choose another user id"});
          }
       });
       var newUser = {id: req.body.id, password: req.body.password};
       Users.push(newUser);
       console.log(JSON.stringify(newUser));
       req.session.user = newUser;
       res.redirect('/protected_page');
     }
});
 
//FUNCTION used below to check if logged in, will be session variable called user
function checkSignIn(req, res, next){
   if(req.session.user){
         next();     //If session exists, proceed to page
   } else {
         var err = new Error("Not logged in!");
         console.log(req.session.user);
         next(err);  //Error, trying to access unauthorized page!
   }
}
                   
//Handler for URI /protectedPage, calls checkSignIn first and only if
// no error will it render protected_page.ejs inside views/pages
app.get('/protected_page', checkSignIn, function(req, res){
     res.render('pages/protected_page', {id: req.session.user.id})
});
                   
//Handler for GET URI /login that renders login.ejs form in views/pages
app.get('/login', function(req, res){
     res.render('pages/login');
});
//Handler for POST URI /login that expects results from html form login.ejs
// including data of id and password.  If present checks if ther user has 
// previously signed up and both user id and password match with what was specified
// and stored in Users[] array.  If so redirects to /protected_page URI.  If id/password
// do not match redirects to login.ejs form in views/pages
app.post('/login', function(req, res){
     console.log(Users);
     if(!req.body.id || !req.body.password){
          res.render('pages/login', {message: "Please enter both id and password"});
     }
     else{
          Users.filter(function(user){
            if(user.id === req.body.id && user.password === req.body.password){
                req.session.user = user;
                res.redirect('/protected_page');
              }
          });
          res.render('pages/login', {message: "Invalid credentials!"});
      }
 });
                   
//Handler for URI /logout that destroys the session including any user information.
app.get('/logout', function(req, res){
    req.session.destroy(function(){
        console.log("user logged out.")
    });
    res.redirect('/login');
});
 
 
 
//**********************************************************************
//STEP 4:  SETUP LISTENER PORT FOR THIS APP
app.listen(app.get('port'), function() {
   console.log('Node app is running on port', app.get('port'));
});
                   

 

STEP 4: Run it

Run the app with the following command:

$ node index.js  

 

 

 

© Lynne Grewe