I want to make sure that a particular link ('New Blog') is only available to myself (username = "admin") and not to the general public. I've written the following if statement but it's throwing an error:
<% if(currentUser.username = "admin") { %>
<ul class="nav navbar-nav">
<li class="active"><i class="fa fa-plus" aria-hidden="true"></i> New Blog <span class="sr-only">(current)</span></li>
</ul>
<% } %>
What is wrong with my logic here??
Routes are as follows:
router.get("/blogs", function(req, res){
Blog.find({}, function(err, blogs){
if(err) {
console.log(err);
} else {
res.render("index", {blogs: blogs});
}
});
});
router.get("/new", function(req, res){
res.render("new");
});
router.get("/blogs/:id", function(req, res){
Blog.findById(req.params.id, function(err, foundBlog){
if(err){
res.redirect("/blogs");
} else {
res.render("show", {blog:foundBlog});
}
});
});
// create route
router.post("/blogs", function(req, res){
req.body.blog.body = req.sanitize(req.body.blog.body);
Blog.create(req.body.blog, function(err, newBlog){
if(err) {
res.render("new");
} else {
res.redirect("/blogs");
}
});
});
// edit route
router.get("/blogs/:id/edit", function(req, res){
// find blog
Blog.findById(req.params.id, function(err, foundBlog){
if(err){
res.redirect("/blogs");
} else {
res.render("edit", {blog: foundBlog});
}
});
});
// update route
router.put("/blogs/:id", function(req,res){
req.body.blog.body = req.sanitize(req.body.blog.body);
Blog.findByIdAndUpdate(req.params.id, req.body.blog, function(err, updatedBlog) {
if(err) {
res.redirect("/");
} else {
res.redirect("/blogs/" + req.params.id);
}
});
});
// delete route
router.delete("/blogs/:id", function(req, res){
Blog.findByIdAndRemove(req.params.id, req.body.blog, function(err, deleteBlog){
if(err) {
res.redirect("/blogs");
} else {
res.redirect("/blogs");
}
});
});
router.get("/", function(req, res){
res.redirect("/blogs");
})
// reg
router.get("/register", function(req, res){
res.render("register");
});
// signup logic
router.post("/register", function(req, res){
var newUser = new User({username: req.body.username, image: req.body.image});
User.register(newUser, req.body.password, function(err, user){
if(err){
res.redirect("/blogs");
}
passport.authenticate("local")(req, res, function(){
res.redirect("/blogs");
});
});
});
// login form
router.get("/login", function(req, res){
res.render("login");
});
// login logic
router.post("/login", passport.authenticate("local", {
successRedirect: "/blogs",
failureRedirect: "/login",
}));
// logout logic
router.get("/logout", function(req, res){
req.logout();
req.flash("success", "You are now logged out");
res.redirect("/blogs");
});
When authentication is successful, Passport attaches the user object to the request object of the express router(req.user). This is achieved via the done(null, user) in your local authentication strategy. You can make the user object to check whether the corresponding user is indeed the admin.
router.post("/blogs", function(req, res){
req.body.blog.body = req.sanitize(req.body.blog.body);
Blog.create(req.body.blog, function(err, newBlog){
if(err) {
res.render("new", {
// Ternary operator which checks if the user object is empty or not
currentUser: req.user ? req.user.currentUser: '',
// I hope currentUser is present in your Schema object
});
} else {
res.redirect("/blogs");
}
});
And then you can check in your view whether it is the correct user or not:
<% if(currentUser === "admin") { %>
<ul class="nav navbar-nav">
<li class="active"><i class="fa fa-plus" aria-hidden="true"></i> New Blog <span class="sr-only">(current)</span> </li>
</ul>
<% } %>
Related
I'm a new programmer :)
I'm trying to build an authentication system using passport.js.
Now, I want to determine the expiration of the cookies, depend on "Remember me" checkbox - For the example I chose: if “remember me” cookie expires after 2 minutes, otherwise cookie expires after 1 minute.
The problem is that it doesn't change the cookie's maxAge (it still 1 minute)
my code:
login.hbs
<body class="border border-2 border" style="margin-top: 15%; margin-right: 30%; margin-left: 30%">
<form action="/login" method="POST" class="form-signing container" style="max-width: 30rem">
<div class="text-center">
<!-- <img class="mb-4" src="public/images/wine4u_logo.jpeg" alt="" width="72" height="72"> -->
<h1 class="h3 mb-3 font-weight-normal">Login</h1>
<p>Please Enter your credentials in order to enter our store.</p>
</div>
<hr>
{{#if error}}
<div class="alert alert-danger">{{error}}</div>
{{/if}}
<div class="mb-3 text-left">
<label for="email" class="form-label"><b>Email</b></label>
<input type="email" placeholder="Enter Email" class="form-control" id="email" name="email" required>
</div>
<div class="mb-3">
<label for="password" class="form-label"><b>Password</b></label>
<input type="password" placeholder="Enter Password" class="form-control" id="password" name="password" required>
</div>
<div class="checkbox mb-3 text-center">
<label>
<input type="checkbox" class="form-label" name="rememberMe" value="remember-me"> Remember me
</label>
<!-- <label for="checkbox"><b>Remember Me?</b></label> -->
<!-- <input type="checkbox" name="rememberMe"> -->
</div>
<div class="text-center">
<button type="submit" class="btn btn-lg btn-primary btn-block">Login</button>
</div>
</form>
<hr>
<form action="/register" class="text-center">
<button type="" class="btn btn-lg btn-secondary btn-block">Sign up page</button>
</form>
<!-- Register -->
</body>
app.js:
if (process.env.NODE_ENV !== "production") {
require("dotenv").config();
}
const express = require("express");
const path = require("path");
const bodyParser = require("body-parser");
const exphbs = require("express-handlebars");
const bcrypt = require("bcrypt");
const passport = require("passport");
const flash = require("express-flash");
const session = require("express-session");
const initializePassport = require("./public/javascript/passport-config");
const methodOverride = require("method-override");
initializePassport(
passport,
(email) => users.find((user) => user.email === email),
(id) => users.find((user) => user.id === id)
);
const app = express();
let users = [];
let cookieLength = 60 * 1000;
// handleBars middleware
app.engine(".hbs", exphbs.engine({ defaultLayout: "main", extname: ".hbs" }));
app.set("view engine", ".hbs");
app.use(bodyParser.json());
app.use(express.urlencoded({ extended: false }));
app.use(flash());
app.use(
session({
secret: process.env.SESSION_SECRET,
resave: false,
saveUninitialized: false,
rolling: true,
cookie: { maxAge: cookieLength },
})
);
app.use(passport.initialize());
app.use(passport.session());
app.use(methodOverride("_method"));
app.get("/", checkAuthenticated, async (req, res) => {
res.render("index", { title: "Welcome to my site" });
});
app.get("/login", checkLoggedIn, async (req, res) => {
res.render("pages/login", {
title: "login page",
noHeader: true,
error: req.flash("error"),
csrf: "CSRF token goes here",
});
});
app.post(
"/login",
checkLoggedIn,
defineCookieLength,
passport.authenticate("local", {
successRedirect: "/",
failureRedirect: "/login",
failureFlash: true,
})
);
app.get("/register", checkLoggedIn, (req, res) => {
res.render("pages/register", { title: "register page", noHeader: true });
});
app.post("/register", async (req, res) => {
try {
const hashedPassword = await bcrypt.hash(req.body.password, 10);
users.push({
id: Date.now().toString(),
username: req.body.name,
email: req.body.email,
password: hashedPassword,
});
console.log("after:", users);
res.redirect("login");
} catch {
res.redirect("/register");
}
});
app.delete("/logout", function (req, res, next) {
req.logout(function (err) {
if (err) {
return next(err);
}
res.redirect("/login");
});
});
app.get("/about", checkAuthenticated, async (req, res) => {
// console.log("users in /login:", users)
res.render("pages/about", { title: "About us" });
});
function defineCookieLength(req, res, next) {
if (req.body.rememberMe === "on") {
req.session.cookie.maxAge = 120 * 1000;
next();
return;
}
next();
}
// validate that the user is already logged in before let him see other pages
function checkAuthenticated(req, res, next) {
if (req.isAuthenticated()) {
return next();
}
res.redirect("/login");
}
// validate that user can't use login/register pages if he is already logged in
function checkLoggedIn(req, res, next) {
if (req.isAuthenticated()) {
return res.redirect("/");
}
next();
}
const PORT = process.env.PORT || 8000;
app.listen(PORT, () => {
console.log(`Server Running on port: http://localhost:${PORT}`);
});
passport-config.js
const LocalStrategy = require("passport-local").Strategy;
const bcrypt = require("bcrypt");
function initialize(passport, getUserByEmail, getUserById) {
const authenticateUser = async (email, password, done) => {
const user = getUserByEmail(email);
if (user == null) {
return done(null, false, { message: "No user with that email" });
}
try {
if (await bcrypt.compare(password, user.password)) {
return done(null, user);
} else {
return done(null, false, { message: "Password incorrect" });
}
} catch (err) {
return done(err);
}
};
passport.use(new LocalStrategy({ usernameField: "email" }, authenticateUser));
passport.serializeUser((user, done) => done(null, user.id));
passport.deserializeUser((id, done) => {
return done(null, getUserById(id));
});
}
module.exports = initialize;
How can I conditionally render from 2 navbar choices using node, EJS, passport and session?
I would like to conditionally render from 2 navbar choices. I am using EJS, passport and session. I tried a few things but nothing worked. The goal is to render a Login nav bar if the client has not been authenticated or a nav bar with options if the client has been authenticated both nav bars using the same rest of the page.
I am posting a lot of code here that I wrote following Brad Traversy’s video “Node.js With Passport Authentication | Full Project” (by the way... thanks Brad. Big fan!). I do believe I am close to the solution in the nav-bar file. I just need a bit of help from someone who really knows what he is doing (I don’t). I would really appreciate it if one of you nice guys could take a look at the files below and tell me what I am missing.
It looks like Tiger Abrodi already asked this same question and it was solved by the Discord team (see How can i conditionally render the navbar using ejs). However, the answer is not shown. I believe this is a very useful solution that should be posted here for other guys so I promise that your solution will remain posted here for anyone else to see.
Thanks guys!
My Home Page; you can see I use "include" to call the nav-bar and this works.
<!-- Navigation Bar ----------------------------------->
<%- include('assets/nav-bar'); %>
<!--------- Main Body --------->
<div class="mainBodyContainter mBC2">
<h3>Busca por Marca:</h3>
<ul>
<li>Marca</li>
<li>Año</li>
<li>Modelo</li>
<li>Sub-Modelo</li>
</ul>
<button class="button">Buscar</button>
</div>
<!-- Right *** Anuncio -->
<%- include ('assets/main-ad') %>
<!----------------- Footings ----------------->
<%- include ('assets/footings') %>
My nav bar; PROBLEM: This decision making is NOT WORKING as it keeps considering user as UNDEFINED. I can verify that the user has been successfully authenticated by checking my dashboard included below.
<!-- -- Navigation Bar Decision -->
<% if (typeof user === 'undefined') { %>
<!---- Navigation Bar NON AUTHENTICATED CLIENT -------->
<div id="navBarHTML">
<nav>
<ul>
<li>Ayuda</li>
<li>Registrate</li>
<li>Acceso</li>
<li>Inicio</li>
</ul>
</nav>
</div>
<% } else { %>
<!---- Navigation Bar AUTHENTICATED CLIENT------------->
<div id="navBarHTML">
<nav>
<ul>
<li>Ayuda</li>
<li>Notificaciones</li>
<li>Mis Publicaciones</li>
<li>Salir</li>
<li>Inicio</li>
<li><a>Bienvenido <%= name %></a></li>
</ul>
</nav>
</div>
<% } %>
Dashboard
<h1>Dashboard</h1>
<br>
<p>Bienvenido <%= name %></p>
<br>
Logout
My index.js; it feeds the user name to my dashboard and it works fine!
const express = require('express');
const router = express.Router();
const { ensureAuthenticated } = require('../config/auth');
// Home page
router.get('/', (req, res) => res.render('home'));
// Dashboard ***PROTECTED FOR NO ACCESS UNLESS LOGGED IN***
router.get('/dashboard', ensureAuthenticated, (req, res) =>
res.render('dashboard', {
name: req.user.name
}));
module.exports = router;
My app.js; it works fine.
const express = require('express');
const expressLayouts = require('express-ejs-layouts');
const mongoose = require('mongoose');
const app = express();
const db = mongoose.connection;
const flash = require('connect-flash');
const session = require('express-session');
const passport = require('passport');
// Passport config
require('./config/passport') (passport);
// Connect to Mongo
mongoose.set('useNewUrlParser', true);
mongoose.set('useUnifiedTopology', true);
mongoose.connect('mongodb://localhost/eyonke_server')
.then(() => console.log('La base de datos de MongoDB conectó correctamente...'))
.catch(err => console.log(err));
// EJS
app.use(expressLayouts);
app.set('view engine', 'ejs');
app.use(express.static(__dirname + '/views'));
// Bodyparser
app.use(express.urlencoded({ extended: false }));
// Express session middleware
app.use(session({
secret: 'secret',
resave: true,
saveUninitialized: true,
}));
// Passport middleware
app.use(passport.initialize());
app.use(passport.session());
// Connect flash
app.use(flash());
// Global Variables
app.use((req, res, next) => {
res.locals.success_msg = req.flash('success_msg');
res.locals.error_msg = req.flash('error_msg');
res.locals.error = req.flash('error');
next();
});
// Routes
app.use('/', require('./routes/index'));
app.use('/users', require('./routes/users'));
const PORT = process.env.PORT || 5000;
app.listen(PORT, console.log(`El servidor de eYonke esta corriendo en el puerto numero ${PORT}...`));
My passport config; works fine!
const LocalStrategy = require('passport-local').Strategy;
const mongoose = require('mongoose');
const bcrypt = require('bcryptjs');
// Load User model
const User = require('../models/User');
module.exports = function(passport) {
passport.use(
new LocalStrategy({ usernameField: 'email'}, (email, password, done) => {
//Match user
User.findOne({ email: email })
.then(user => {
if(!user) {
return done(null, false, { message: 'Email no registrado' });
}
// Match password
bcrypt.compare(password, user.password, (err, isMatch) => {
if(err) throw err;
if(isMatch) {
return done(null, user);
} else {
return done(null, false, { message: 'Contraseña incorrecta' });
}
});
})
.catch(err => console.log(err));
})
);
// Session
passport.serializeUser((user, done) => {
done(null, user.id);
});
passport.deserializeUser((id, done) => {
User.findById(id, (err, user) => {
done(err, user);
});
});
}
auth.js; works fine!
module.exports = {
ensureAuthenticated: function(req, res, next) {
if(req.isAuthenticated()) {
return next();
}
req.flash('error_msg', 'Necesitas entrar a tu cuenta para accesar este recurso');
res.redirect('/'); /*if not authenticated, then redirected to home page*/
}
}
My users.js for registering and logging in/out; works fine!
const express = require('express');
const router = express.Router();
const bcrypt = require('bcryptjs');
const passport = require('passport');
//User model
const User = require('../models/User');
//Login page
router.get('/login', (req, res) => res.render('login'));
//Registration page
router.get('/register', (req, res) => res.render('register'));
// Register Handle
router.post('/register', (req, res) => {
const { name, email, password, password2 } = req.body;
let errors = [];
//Check for errors
//Check required fields
if(!name || !email || !password || !password2) {
errors.push({ msg: 'Por favor llena todos los campos'});
}
// Check passwords match
if(password !== password2) {
errors.push({ msg: 'Las contraseñas no son iguales'});
}
// Check password length
if(password.length < 6) {
errors.push({ msg: 'La contraseña debe tener al menos 6 caracteres'});
}
if(errors.length > 0) {
res.render('register', {
errors,
name,
email,
password,
password2
});
} else {
// Validation passed
User.findOne({ email: email })
.then(user => {
if(user) {
// User exists
errors.push({ msg: 'Email ya está registrado en eYonke'});
res.render('register', {
errors,
name,
email,
password,
password2
});
} else {
const newUser = new User({
name,
email,
password
});
// Hash Password
bcrypt.genSalt(10, (err, salt) =>
bcrypt.hash(newUser.password, salt, (err, hash) => {
if(err) throw err;
// set password to hashed
newUser.password = hash;
// Save user
newUser.save()
.then(user => {
req.flash('success_msg', 'Te has registrado exitosamente');
res.redirect('/users/login');
})
.catch(err => console.log(err));
}))
}
});
}
});
// Login handle
router.post('/login', (req, res, next) => {
passport.authenticate('local', {
successRedirect: '/', /*'/dashboard',*/
failureRedirect: '/users/login',
failureFlash: true
})(req, res, next);
});
// Logout handle
router.get('/logout', (req, res) => {
req.logOut();
req.flash('success_msg', 'Tu sessión ha terminado');
res.redirect('/');
});
module.exports = router;
I was able to find Tiger A. and he kindly helped me to solve it. The changes I made to my code are as follows:
1.- in app.js I added a global variable as follows:
app.use((req, res, next) => {
res.locals.user = req.user;
next();
});
2.- in my navbar I replace the decision line with the following:
<% if (!user) { %>
and that did the trick. Now I am able to decide which nav bar to use depending if the user has been authenticated or not.
I have an Express server on the backend that uses Passport.js for authentication. Even when successfully authenticated, a 404 error is shown in the webbrowser, when redirecting to '/about', '/login', or any other path (all those paths exists on the frontend), or even when not redirecting. The only time a 404 is not shown is if a redirect to '/' is made. I will include the relevant code snippets below.
users.js
router.post('/api/login', function(req, res, next) {
passport.authenticate('local', function(err, user, info) {
if (err) { return next(err); }
if (!user) { return res.redirect('/login'); }
req.logIn(user, function(err) {
if (err) { return next(err); }
// res.statusCode is still 200 here!!!!!!!!
return res.redirect('/about');
});
})(req, res, next);
})
Alternative users.js (has same issue)
router.post('/api/login',
passport.authenticate('local', { successRedirect: '/about',
failureRedirect: '/login' }))
passportLocalStrategy.js
const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;
const init = require('./passportSessionConfig');
const knex = require('../db/connection');
const authUtils = require('./utils')
init();
passport.use(new LocalStrategy({
usernameField: 'email',
passwordField: 'password',
},
function (username, password, done) {
// check to see if the username exists
knex('users')
.where({ 'email': username })
.orWhere({ username })
.first()
.then((results) => {
if (!results) return done(null, false);
if (!authUtils.comparePass(password, results.password)) {
return done(null, false);
} else return done(null, results);
})
.catch((err) => { return done(err); });
}));
module.exports = passport;
This is the frontend javascript code that made the request (Vue.js)
methods: {
login: function(e) {
e.preventDefault();
let data = {
email: this.email,
password: this.password,
returnTo: window.location.pathname
};
this.axios
.post("/api/login", data)
.then(response => {
console.log("Logged in");
this.$router.push("/about");
})
.catch(errors => {
console.log("Cannot log in");
console.log(errors);
});
}
}
This is the 404 error from the webbrowser
I am new to express and I was able to get most of it to work until I wanted to create a delete button.
I am having difficulty getting my delete button to work all the time. It works at random moment and other times it does not work and when it does not work the following error appears:
{ CastError: Cast to ObjectId failed for value "undefined" at path "_id" for model "User"
Code below:
Both index.js and users.js files are in routes directory
//user - file in module directory
var mongoose = require('mongoose');
var bcrypt = require('bcryptjs');
var UserSchema = mongoose.Schema({
username: {
type: String,
index: true
},
password: {
type: String
},
email: {
type: String
},
name: {
type: String
},
isAdmin: {
type: Boolean,
default: false
}
});
var User = module.exports = mongoose.model('User', UserSchema);
module.exports.createUser = function(newUser, callback){
bcrypt.genSalt(10, function(err, salt) {
bcrypt.hash(newUser.password, salt, function(err, hash) {
newUser.password = hash;
newUser.save(callback);
});
});
}
module.exports.getUserByUsername = function(username, callback){
var query = {username: username};
User.findOne(query, callback);
}
module.exports.getUserById = function(id, callback){
User.findById(id, callback);
}
module.exports.comparePassword = function(candidatePassword, hash, callback){
bcrypt.compare(candidatePassword, hash, function(err, isMatch){
if(err) throw err;
callback(null, isMatch);
});
}
<!--page with delete button-->
<section class="jumbotron">
<div class="container">
<h1 class="jumbotron-heading text-center">Users Page</h1>
</div>
<div>
<ul class="list-group">
{{#each users}}
<li class="list-group-item">{{this.name}}</li>
{{/each}}
</ul>
</div>
</secion>
//main.js - file in the javascript directory
$(document).ready(function(){
$('.delete-user').on('click', function(e) {
$target = $(e.target);
const id = $target.attr('data-id');
$.ajax({
type: 'DELETE',
url: '/users/user/'+id,
success: function(response){
alert('Deleting User');
window.location.href='/users/users';
},
error: function(err){
console.log(err);
}
});
});
});
//users.js - file
var express = require('express');
var router = express.Router();
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var User = require('../modules/user');
// Admin Page
router.get('/admin', function(req, res){
res.render('admin');
});
// Login Page
router.get('/login', function(req, res){
res.render('login');
});
// Registeration Page
router.get('/register', function(req, res){
res.render('register');
});
// Users
router.get('/users', function(req, res) {
User.find({}, function(err, users) {
if(err) {
console.log(err);
} else {
res.render('users', {
users: users
});
}
});
});
// Individual Users
router.get('/user/:id', function(req, res) {
User.findById(req.params.id, function(err, users) {
res.render('user', {
users: users
});
});
});
// Delete Users
router.delete('/user/:id', function(req, res) {
let query = {_id:req.params.id};
User.remove(query, function(err){
if(err){
console.log(err);
}
res.send('Success');
});
});
// Create post request from form to server
router.post('/register', function(req, res){
var name = req.body.name;
var email = req.body.email;
var username = req.body.username;
var password = req.body.password;
var password2 = req.body.password2;
var adminCode = req.body.adminCode;
//Validation
req.checkBody('name', 'Name is required').notEmpty();
req.checkBody('email', 'Email is Required').notEmpty();
req.checkBody('email', 'Email is not valid').isEmail();
req.checkBody('username', 'Username is required').notEmpty();
req.checkBody('password', 'Password is required').notEmpty();
req.checkBody('password2', 'Passwords do not match').equals(req.body.password);
var errors = req.validationErrors();
if(errors){
res.render('register',{
errors:errors
});
} else {
var newUser = new User({
name: name,
email: email,
username: username,
password: password
});
if(adminCode === 'secretcode123') {
newUser.isAdmin = true;
}
User.createUser(newUser, function(err, user){
if(err) throw err;
console.log(user);
});
req.flash('success_msg', 'You are registered and can now login');
res.redirect('/users/register');
}
});
passport.use(new LocalStrategy(
function(username, password, done) {
User.getUserByUsername(username, function(err, user) {
if (err) throw err;
if (!user) {
return done(null, false, { message: 'Unknown User' });
}
User.comparePassword(password, user.password, function(err, isMatch){
if(err) throw err;
if(isMatch) {
return done(null, user);
} else {
return done(null, false, {message: 'Invalid password'});
}
});
});
}));
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
User.getUserById(id, function(err, user) {
done(err, user);
});
});
router.post('/login',
passport.authenticate('local', {successRedirect: '/', failureRedirect: '/users/login', failureFlash: true }),
function(req, res) {
res.redirect('/');
});
router.get('/logout', function(req, res){
req.logout();
req.flash('success_msg', 'You are logged out');
res.redirect('/users/login');
});
module.exports = router;
//indexjs - file
var express = require('express');
var router = express.Router();
// Home Page
router.get('/', ensureAuthenticated, function(req, res){
res.render('index');
});
function ensureAuthenticated(req, res,next){
if(req.isAuthenticated()){
return next();
} else {
//req.flash('error_msg', 'You are not logged in');
res.redirect('/users/login');
}
}
module.exports = router;
code here
can someone please advise what i am doing wrong.
It seems like i was able to correct the error. I had to move my data-id element from from my div tag to my anchor tag: see code below:
<section class="jumbotron">
<div class="container">
<h1 class="jumbotron-heading text-center">User Page</h1>
<h1 class="text-center">{{users.name}}</h1>
</div>
<div class="button">
<button class="btn btn-danger delete-user"/*it was here first*/><a href="#" /*now it is here*/data-id={{users._id}}>Delete</a></button>
</div>
</secion>
I'm trying to figure out where the error lies in my authentication code that is creating an endless loop every time I try to login. I think it is within the local strategy passport.use('local', new LocalStrategy section of my code because my console.log(req.body.email); passes back the correct value that was inputted in the field and a query is logged that uses the findOne value, but none of the other console.log are being triggered (one for a email error, another for password error and one for success).
Example: trying to login with test#test.com email address
test#test.com
Executing (default): SELECT `user_id`, `first_name` AS `firstName`, `last_name` AS `lastName`, `email`, `password`, `createdAt`, `updatedAt` FROM `user` AS `user` LIMIT 1;
user.js:
module.exports = function(sequelize, DataTypes) {
var User = sequelize.define('user', {
user_id: {
type: DataTypes.INTEGER,
autoIncrement: true,
primaryKey: true
},
firstName: {
type: DataTypes.STRING,
field: 'first_name'
},
lastName: {
type: DataTypes.STRING,
field: 'last_name'
},
email: DataTypes.STRING,
password: DataTypes.STRING,
}, {
freezeTableName: true
});
return User;
}
db-index.js:
var Sequelize = require('sequelize');
var path = require('path');
var config = require(path.resolve(__dirname, '..', '..','./config/config.js'));
var sequelize = new Sequelize(config.database, config.username, config.password, {
host:'localhost',
port:'3306',
dialect: 'mysql'
});
sequelize.authenticate().then(function(err) {
if (!!err) {
console.log('Unable to connect to the database:', err)
} else {
console.log('Connection has been established successfully.')
}
});
var db = {}
db.User = sequelize.import(__dirname + "/user");
db.sequelize = sequelize;
db.Sequelize = Sequelize;
sequelize.sync();
module.exports = db;
site-routes.js:
var express = require('express');
var siteRoutes = express.Router();
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var models = require('../models/db-index');
/*==== Passport Configuration ====*/
// Serialize sessions
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
model.User.find({where: {id: id}}).success(function(user){
done(null, user);
}).error(function(err){
done(err, null);
});
});
passport.use('local', new LocalStrategy({
passReqToCallback : true,
usernameField: 'email'
},
function(req, email, password, done) {
console.log(req.body.email);
//Find user by email
models.User.findOne({ email: req.body.email }, function(err, user) {
//If there is an error, return done
if (err) { return done(err); }
//If user does not exist, log error and redirect
if (!user) {
console.log('No email')
return done(null, false, req.flash('message', 'Email not found.'));
}
//If user exists, but wrong password
if (!user.validPassword(password)) {
console.log('Password fail');
return done(null, false, { message: 'Incorrect password.' });
}
//If all credentials match, return user
console.log('Attempting login');
return done(null, user);
console.log('Successful login');
});
}
));
/*==== Index ====*/
siteRoutes.get('/', function(req, res){
res.render('pages/index.hbs');
});
/*==== Login ====*/
siteRoutes.route('/login')
.get(function(req, res){
res.render('pages/login.hbs');
})
.post(passport.authenticate('local', {
successRedirect: '/',
failureRedirect: '/sign-up',
failureFlash: true
}));
siteRoutes.route('/sign-up')
.get(function(req, res){
res.render('pages/sign-up.hbs');
})
.post(function(req, res){
models.User.create({
firstName: req.body.firstName,
lastName: req.body.lastName,
email: req.body.email,
password: req.body.password
}).then(function() {
res.redirect('/');
}).catch(function(error){
res.send(error);
})
});
module.exports = siteRoutes;
login.hbs:
<!DOCTYPE html>
<head>
{{> head}}
</head>
<body>
{{> navigation}}
<div class="container">
<div class="col-md-6 col-md-offset-3">
<form action="/login" method="post">
<label for="login-username">Username</label>
<input type="text" class="form-control" id="login-username" name="email" placeholder="username or email">
<br />
<label for="login-password">Password</label>
<input type="password" class="form-control" id="login-password" name="password">
<div class="login-buttons">
<button type="submit">Login</button>
</div>
</form>
Don't have an account? Then register here!
<br />
Forgot your password?
</div>
</div>
</body>
You are passing a callback function as a second argument to models.User.findOne, but Sequelize functions don't take callbacks. Instead they return a promise. Your code in site-routes.js should look something like this:
passport.use('local', new LocalStrategy({
passReqToCallback: true,
usernameField: 'email'
},
function(req, email, password, done) {
console.log(req.body.email);
//Find user by email
models.User.findOne({
email: req.body.email
})
.then(function(user) {
// handle login here, user will be falsey if no user found with that email
})
.catch(function(err) {
// either findOne threw an exception or it returned a rejected promise
});
}
));
For a full-fledged example of local authentication using passport.js and Sequelize you can see my login-fiddle. Here is a perma-link to the passport local authentication strategy.