This tutorial is how to create user authentication or login in the Node.js application with the combination of Express.js, Mongoose.js, and Passport.js. All of those libraries, modules, and dependencies are ready to use in the Node environment. And we will use Jade as a template engine with Bootstrap 3 as a responsive CSS framework for making styling fast and easy. As usual, let's jump to the tutorial.
Jumps to the steps:
- Create Express.js web application
- Install Mongoose.js and Passport.js modules and dependencies
- Create Mongoose.js User Model
- Create Controller for Authentication
- Create Express Routes
- Create Express Views
- Run and Test the Node, Express, Mongoose Authentication Application
Passport.js is authentication (login) or security middleware for the Node.js environment.
It's a flexible and works great with Express.js and also supported OAuth authentication, Facebook, Twitter, etc strategies. This time we will combine the authentication or login in the Node.js/Express.js web application. Authentication or login mechanism will fully be handled by Passport.js. The flow for this Node.js, Express.js, Mongoose.js, and Passport.js tutorial will be like this.
Before jump the main steps, make sure you have installed Node.js (recommended version) and MongoDB server. The rest frameworks, modules, and libraries will be installed in the Node.js environment.
Create Express.js web application
We assume that you already installed all required tools like Node.js and Express.js application generator. Open terminal or cmd then go to the projects folder and run this command.
express node-passport-auth
Different from previous Node.js tutorial that now we are not using '--ejs' prefix because now, we will use 'jade' as template engine that comes as default Express.js application generation. Go to the newly created folder then install the NPM module.
cd node-passport-auth && npm install
And here is generated application project structure.
Now, you can run the application to make sure everything working properly. You can use one of the commands below.
nodemon
or
npm start
If you see this page, that would be easy to continue to the next steps.
Install Mongoose.js and Passport.js modules and dependencies
Now, we have to add database ORM/ODM for connection Node.js application with MongoDB database. For that, type this command after you stop the application.
npm install mongoose --save
For Passport.js we have to run this command.
npm install passport passport-local passport-local-mongoose --save
We have to install Express-Session too for storing authentication token in cookies.
npm install express-session --save
Open and edit app.js from the root of the project folder. Add Mongoose.js to 'require' and call connection to MongoDB.
var mongoose = require('mongoose');
mongoose.Promise = global.Promise;
mongoose.connect('mongodb://localhost/node-auth')
.then(() => console.log('connection succesful'))
.catch((err) => console.error(err));
Add require for passport and passport-local.
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
In 'app.use' section add these lines for initializing passport and express-session.
app.use(require('express-session')({
secret: 'keyboard cat',
resave: false,
saveUninitialized: false
}));
app.use(passport.initialize());
app.use(passport.session());
Now, add passport configuration.
var User = require('./models/user');
passport.use(new LocalStrategy(User.authenticate()));
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());
Now run again the application, but don't forget to run MongoDB server in another terminal tab. If you run again your application and see the message below, then your application mongoose configuration is ok.
[nodemon] 1.11.0
[nodemon] to restart at any time, enter `rs`
[nodemon] watching: *.*
[nodemon] starting `node ./bin/www`
connection succesful
Create Mongoose.js User Model
This time to create models for authentication requirement. Create a new folder in the root of the project folder then add the file for User Model.
mkdir models
touch models/User.js
Open and edit models/User.js then add these lines of codes.
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var passportLocalMongoose = require('passport-local-mongoose');
var UserSchema = new Schema({
username: String,
password: String
});
UserSchema.plugin(passportLocalMongoose);
module.exports = mongoose.model('User', UserSchema);
Create Express Controller for Authentication or Login
To control access from views to models and vice-versa, we will create Controller for authentication or login. This is just implementing a basic MVC pattern. Create controllers folder then create a controller file on the root of the project folder.
mkdir controllers
touch controllers/AuthController.js
Open and edit AuthController.js then add all these lines of codes.
var mongoose = require("mongoose");
var passport = require("passport");
var User = require("../models/User");
var userController = {};
// Restrict access to root page
userController.home = function(req, res) {
res.render('index', { user : req.user });
};
// Go to registration page
userController.register = function(req, res) {
res.render('register');
};
// Post registration
userController.doRegister = function(req, res) {
User.register(new User({ username : req.body.username, name: req.body.name }), req.body.password, function(err, user) {
if (err) {
return res.render('register', { user : user });
}
passport.authenticate('local')(req, res, function () {
res.redirect('/');
});
});
};
// Go to login page
userController.login = function(req, res) {
res.render('login');
};
// Post login
userController.doLogin = function(req, res) {
passport.authenticate('local')(req, res, function () {
res.redirect('/');
});
};
// logout
userController.logout = function(req, res) {
req.logout();
res.redirect('/');
};
module.exports = userController;
Create Express Routes
We need to create routes for the authentication mechanism. Open and edit routes/index.js then add this all lines of codes.
var express = require('express');
var router = express.Router();
var auth = require("../controllers/AuthController.js");
// restrict index for logged in user only
router.get('/', auth.home);
// route to register page
router.get('/register', auth.register);
// route for register action
router.post('/register', auth.doRegister);
// route to login page
router.get('/login', auth.login);
// route for login action
router.post('/login', auth.doLogin);
// route for logout action
router.get('/logout', auth.logout);
module.exports = router;
Create Express Views
Now is the time for creating user interface or views. Open and edit views/layout.jade then add bootstrap for styling view via CDN.
doctype html
html
head
title= title
link(rel='stylesheet', href='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css', integrity='sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u', crossorigin='anonymous')
link(rel='stylesheet', href='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css', integrity='sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp', crossorigin='anonymous')
link(rel='stylesheet', href='/stylesheets/style.css')
body
nav.navbar.navbar-default
div.container-fluid
div.navbar-header
button.navbar-toggle.collapsed(type='button', data-toggle='collapse', data-target='#bs-example-navbar-collapse-1', aria-expanded='false')
span.sr-only Toggle navigation
span.icon-bar
span.icon-bar
span.icon-bar
a.navbar-brand(href='#') Node.js Auth
div.collapse.navbar-collapse(id='bs-example-navbar-collapse-1')
ul.nav.navbar-nav.navbar-right
if (!user)
li
a(href='/login') Login
li
a(href='/register') Register
if (user)
li
a Welcome #{user.name}
li
a(href='/logout') Logout
div.container
div.content
block content
script(src='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js', integrity='sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa', crossorigin='anonymous')
Open and edit views/index.jade then replace all codes with this.
extends layout
block content
h1 Node.js, Express.js, Mongoose.js and Passport.js
p User Authentication Example
Create new files for login and register form.
touch views/login.jade
touch views/register.jade
Open and edit views/login.jade then add these lines of codes.
extends layout
extends layout
block content
.container
form.form-signin(role='form', action='/login', method='post')
h2.form-signin-heading Please sign in
label.sr-only(for='inputEmail')
input.form-control(type='text', name='username', id='inputEmail', placeholder='Username', required, autofocus)
input.form-control(type='password', name='password', id='inputPassword', placeholder='Password')
button.btn.btn-lg.btn-primary.btn-block(type='submit') LOGIN
Open and edit views/register.jade then add these lines of codes.
extends layout
block content
.container
form.form-signin(role='form', action="/register",method="post", style='max-width: 300px;')
h2.form-signin-heading Sign Up here
input.form-control(type='text', name="name", placeholder='Your Name')
input.form-control(type='text', name="username", placeholder='Your Username')
input.form-control(type='password', name="password", placeholder='Your Password')
button.btn.btn-lg.btn-primary.btn-block(type='submit') Sign Up
Next, we have to do a little styling for these views. Open and edit public/stylesheets/style.css then replace all code with this.
body {
background-color: #eee;
}
.form-signin {
max-width: 330px;
padding: 15px;
margin: 0 auto;
}
.form-signin .form-signin-heading,
.form-signin .checkbox {
margin-bottom: 10px;
}
.form-signin .checkbox {
font-weight: normal;
}
.form-signin .form-control {
position: relative;
height: auto;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
padding: 10px;
font-size: 16px;
}
.form-signin .form-control:focus {
z-index: 2;
}
.form-signin input[type="email"] {
margin-bottom: -1px;
border-bottom-right-radius: 0;
border-bottom-left-radius: 0;
}
.form-signin input[type="password"] {
margin-bottom: 10px;
border-top-left-radius: 0;
border-top-right-radius: 0;
}
Run and Test the Node, Express, Mongoose Authentication or Login Application
Finally, we have to try and run the application to see if all functionality is working fine.
nodemon
Open a browser and point to 'localhost:3000'. You should see this page on the browser.
You can start register then it will automatically log in.
Full source code on Github.
This tutorial uses basic Node.js and Express.js with help of Mongoose.js, Passport.js, and Bootstrap. Feel free to give us input or suggestion in the comment below.
That just the basic. If you need more deep learning about MEAN Stack, Angular, and Node.js, you can take the following cheap course:
- Master en JavaScript: Aprender JS, jQuery, Angular 8, NodeJS
- Angular 8 - Complete Essential Guide
- Learn Angular 8 by creating a simple Full Stack Web App
- Angular 5 Bootcamp FastTrack
- Angular 6 - Soft & Sweet
- Angular 6 with TypeScript
Thanks.