This week I worked on adding authentication to the YelpCamp app I was building through the bootcamp tutorials. I used the npms express-session, passport, passport-local, and passport-local-mongoose. The first I did was call the…
This week I worked on adding authentication to the YelpCamp app I was building through the bootcamp tutorials. I used the npms express-session, passport, passport-local, and passport-local-mongoose. The first I did was call the npms and configure passport so that it ran properly on the app. This included making the app start a session when a user logged in and make sure that passport was able to run user authentication method.
//Passport Configuration
app.use(require("express-session")({
secret:"This is the YelpCamp secret!",
resave: false,
saveUninitialize: false
}));
app.use(passport.initialize());
app.use(passport.session());
passport.use(new LocalStrategy(User.authenticate()));
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());
After setting up passport I created a user model that was then imported into our main app file. In this user model my user mongoose schema is held. We also called passport-local-mongoose which allowed us to export our user schema with access to passport methods.
var mongoose = require("mongoose");
var passportLocalMongoose = require("passport-local-mongoose");
var UserSchema = new mongoose.Schema({
username: String,
password: String
});
UserSchema.plugin(passportLocalMongoose);
module.exports = mongoose.model("User", UserSchema);
Once I had my user model was working properly I started creating the signup, login, and logout routes. The first routes I created were the sign up routes which was making sure the register page was called and then having the post route which handled he sign up logic. Then I created the register page which was an ejs file and it contained the registration form.
app.get("/register", function(req, res) {
res.render("register");
});
//handle sign up logic
app.post("/register", function(req, res) {
var newUser = new User({username: req.body.username});
User.register( newUser, req.body.password, function(err, user){
if(err){
console.log(err);
return res.render("register");
}
passport.authenticate("local")(req, res, function(){
res.redirect("/campgrounds");
});
});
});
<% include ./partials/header %>
<h1> Sign Up! </h1>
<form action="/register" method="POST">
<input type="text" name="username" placeholder="username"/>
<input type="password" name="password" placeholder="password"/>
<button> Sign Up </button>
</form>
<% include ./partials/footer %>
The second set of routes I created were the login routes. The first route held the call for the sign page and then the second route handled the login logic. The second route I had to place a middle ware that made sure the user logging was authenticated before sending them to a different page. After both routes were running I created the ejs file that held the login form.
//show login form
app.get("/login", function(req, res){
res.render("login");
});
// handling login logic
app.post("/login", passport.authenticate("local",
{
successRedirect:"/campgrounds",
failureRedirect:"/login"
}), function(req, res) {
});
<% include ./partials/header %>
<h1> Login! </h1>
<form action="/login" method="POST">
<input type="text" name="username" placeholder="username"/>
<input type="password" name="password" placeholder="password"/>
<input type="submit" value="Login"/>
</form>
<% include ./partials/footer %>
The last route that I had to include was the log out page for which I had to only create one route because passport allows us to use a method that automatically runs the logic needed to log out a user. Then once the user was logged out I redirected them to a different page.
//logout route
app.get("/logout", function(req, res) {
req.logout();
res.redirect("/campgrounds");
})
The last thing thing I worked on this section was making sure that the right links were showing when a user was logged out and when they were logged in. This involved showing the login and sign up links when a user was not logged in and only showing the log out link when they were logged in. I also made sure that a user wasn’t able to add comments to a post when they were logged in. To do this I had to create a middleware that detected if a user was logged in and the add it to the comment routes. If a user wasn’t logged in and tried to add a comment it would then send them to the login page.
//middleware
function isLoggedIn(req, res, next){
if(req.isAuthenticated()){
return next();
}
res.redirect("/login");
}
<!DOCTYPE html>
<html>
<header>
<title> YelpCamp </title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<link rel="stylesheet" href="/stylesheets/main.css">
</header>
<body>
<nav class="navbar navbar-default">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="/"> YelpCamp </a>
</div>
<div class="collapse navbar-collapse">
<ul class="nav navbar-nav navbar-right">
<% if(!currentUser){ %>
<li> <a href="/login"> Login </a> </li>
<li> <a href="/register"> Sign Up </a> </li>
<% }else{ %>
<li> <a href="#"> Signed in as <%= currentUser.username %> </a> </li>
<li> <a href="/logout"> Logout </a> </li>
<% } %>
</ul>
</div>
</div>
</nav>
It was great learning about user authentication and I’m also 2-3 sections away from deploying this app so I’m really looking forward to learning how to deploy it.