Section 31 – Lesson 406 – Complete 2020 Web Development Bootcamp

Lesson 406 – Using Passport.js to Add Cookies and Sessions?

The first step is to install the passport, passport-local, passport-local-mongoose and express-session npm packages by typing this in the terminal –

npm i passport passport-local passport-local-mongoose express-session

Next you have to require express-session by typing this code in your app.js file –

const session = require('express-session');

The next step is to require the passport and passport-local-mongoose packages by typing this code in your app.js file –

const passport = require('passport');
const passportLocalMongoose = require('passport-local-mongoose');

Then you set up the session. It is important that the code to set up the is placed just below the app.use(bodyParser.urlencoded) code and just above the mongoose.connect code in your app.js file like this –

app.use(bodyParser.urlencoded({
	extended: true
}));

app.use(session({

	secret: "Our little secret.",
	resave: false,
	saveUninitialized: false

}));

mongoose.connect("mongodb://localhost:27017/userDB", {useNewUrlParser: true, useUnifiedTopology: true});

The next step is to initialize passport by typing this code in your app.js file just below the app.use(session) code –

app.use(passport.initialize());
app.use(passport.session());

The next step is to set up our passport-local-mongoose package. You do this by adding the following code right below the const userSchema code in your app.js file –

userSchema.plugin(passportLocalMongoose);

Then right below the const User code, you add this code –

passport.use(User.createStrategy());

passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());

When you save the app.js file and restart the server by typing this in the terminal –

nodemon app.js

you get this deprecation warning –

(node:19041) DeprecationWarning: collection.ensureIndex is deprecated. Use createIndexes instead.

To fix this, you need to type this code just below the mongoose.connect code in your app.js file –

mongoose.set("useCreateIndex", true);

The next step is to set up the app.post(“/register”) route. This is the code –

app.post("/register", function(req, res) {

	User.register({username: req.body.username}, req.body.password, function(err, user) {
		if (err) {
			console.log(err);
			res.redirect("/register");
		} else {
			passport.authenticate("local")(req, res, function() {
				res.redirect("/secrets");
			});
		}
	});

});

Then you add a new app.get(“/secret”) route using this code –

app.get("/secrets", function(req, res) {
	if (req.isAuthenticated()) {
		res.render("secrets");
	} else {
		res.redirect("/login");
	}
});

The next step is to set up app.post(“/login”) route. This is the code –

app.post("/login", function(req, res) {
	
	const user = new User({
		username: req.body.username,
		password: req.body.password
	});

	req.login(user, function(err) {
		if (err) {
			console.log(err);
		} else {
			passport.authenticate("local")(req, res, function() {
			res.redirect("/secrets");
			});
		}
	});

});

The last step is to define a logout route. This is the code –

app.get("/logout", function(req, res) {
	req.logout();
	res.redirect("/");
});

This is the entire app.js file code which has been refactored to use passport.js for authentication, cookies and sessions –

//jshint esversion:6
require('dotenv').config();
const express = require("express");
const bodyParser = require("body-parser");
const ejs = require("ejs");
const mongoose = require("mongoose");
const session = require('express-session');
const passport = require('passport');
const passportLocalMongoose = require('passport-local-mongoose');


const app = express();

app.use(express.static("public"));
app.set('view engine', 'ejs');
app.use(bodyParser.urlencoded({
	extended: true
}));

app.use(session({

	secret: "Our little secret.",
	resave: false,
	saveUninitialized: false

}));

app.use(passport.initialize());
app.use(passport.session());

mongoose.connect("mongodb://localhost:27017/userDB", {useNewUrlParser: true, useUnifiedTopology: true});
mongoose.set("useCreateIndex", true);

const userSchema = new mongoose.Schema ({
	email: String,
	password: String
});

userSchema.plugin(passportLocalMongoose);

const User = new mongoose.model("User", userSchema);

passport.use(User.createStrategy());

passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());

app.get("/", function(req, res){
  res.render("home");
});

app.get("/login", function(req, res){
  res.render("login");
});

app.get("/register", function(req, res){
  res.render("register");
});

app.get("/secrets", function(req, res) {
	if (req.isAuthenticated()) {
		res.render("secrets");
	} else {
		res.redirect("/login");
	}
});

app.get("/logout", function(req, res) {
	req.logout();
	res.redirect("/");
});

app.post("/register", function(req, res) {

	User.register({username: req.body.username}, req.body.password, function(err, user) {
		if (err) {
			console.log(err);
			res.redirect("/register");
		} else {
			passport.authenticate("local")(req, res, function() {
				res.redirect("/secrets");
			});
		}
	});
	

});

app.post("/login", function(req, res) {
	
	const user = new User({
		username: req.body.username,
		password: req.body.password
	});

	req.login(user, function(err) {
		if (err) {
			console.log(err);
		} else {
			passport.authenticate("local")(req, res, function() {
			res.redirect("/secrets");
			});
		}
	});

});



app.listen(3000, function(){
  console.log("Server started on port 3000.");
});