Skip to main content

Build Auth & Sessions into our Fruits App Part 3

Lesson Objectives

  • add sessions controller (no model - why?)
  • add logic to check password

Set up

  • on same level as package.json
  • npm install express-session
  • configure express session

in server.js

in dependencies

server.js
const session = require("express-session");

in middleware section

server.js
app.use(
session({
secret: process.env.SECRET, //a random string do not copy this value or your stuff will get hacked
resave: false, // default more info: https://www.npmjs.com/package/express-session#resave
saveUninitialized: false, // default more info: https://www.npmjs.com/package/express-session#resave
})
);

in .env add

.env
SECRET=FeedMeSeymour
  • We only need the routes for our user
  • the new form to log in
  • the post route to create a new session
  • the delete route to destroy a session

Sessions Controller

in server.js

server.js
const sessionsController = require("./controllers/sessions_controller.js");
app.use("/sessions", sessionsController);

in controllers/sessions_controller.js

controllers/sessions_controller.js
const bcrypt = require("bcrypt");
const express = require("express");
const sessions = express.Router();
const User = require("../models/users.js");

sessions.get("/new", (req, res) => {
res.render("sessions/new.ejs", { currentUser: req.session.currentUser });
});

// on sessions form submit (log in)
sessions.post("/", (req, res) => {
// username is found and password matches
// successful log in

// username is not found - who cares about password if you don't have a username that is found?
// unsuccessful login

// username found but password doesn't match
// unsuccessful login

// Step 1 Look for the username
try {
const foundUser = await User.findOne({ username: req.body.username });
if (!foundUser) {
res.send('<a hred="/">Sorry, no user found </a>);
} else {
if (bcrypt.compareSync(req.body.password, foundUser.password)) {
req.session.currentUser = foundUser;
res.redirect("/");
} else {
res.send( '<a href="/">password does not match</a>)
}
}
} catch (error) {
console.log(error);
};
});

sessions.delete("/", (req, res) => {
req.session.destroy(() => {
res.redirect("/");
});
});

module.exports = sessions;

Refactoring

  • in every get route let's give access to the user

add the following to

controllers/fruits.js
const context = {
...context, // original context
currentUser: req.session.currentUser
}
  • fruits.get/new
  • fruits.get/:id/edit (update)
  • fruits.get/:id (show)
  • fruits.get/ (index)
  • sessions.get/new
  • users.get/new

Let's update the nav partial

partials/nav.ejs
<ul class="right">
<li><a href="/fruits/new">Create a new Fruit</a></li>
<% if (currentUser) { %>
<li>Welcome <%= currentUser.username %></li>
<li>
<form action="/sessions?_method=DELETE" method="POST">
<input type="submit" value="Log Out" class="btn-small red" />
</form>
</li>
<% } else { %>
<li><a href="/users/new">Sign Up</a></li>
<li><a href="/sessions/new">Log In</a></li>
<% } %>
</ul>

Now, whenever we are logged in the nav bar should look like this

Navbar Logged In