I am trying to implement a simple user login and signup page for my application.
The signup page works and everything is getting stored in mongodb correctly. However, when I try to login it it does not seem to work. It is supposed to redirect to my root page but it will not do that. It always redirect back to /users/login
I've been going through a tutorial online so I do not understand why this isn't working. Here are the relevant files files.
user.js file
const express = require('express');
const router = express.Router();
const bcrypt = require('bcryptjs');
const passport = require('passport');
let User = require('../models/user');
// Load register form
router.get('/register', function(req, res) {
res.render('register', {
title : 'Register',
errors : req.flash('success')
});
});
// Submit register form
router.post('/register', function(req, res) {
// Get the fields from the form
const firstname = req.body.firstname;
const lastname = req.body.lastname;
const email = req.body.email;
const pass = req.body.pass;
const pass2 = req.body.pass2;
// Verify body is not empty.
req.checkBody('firstname', 'First name is required').notEmpty();
req.checkBody('lastname', 'Last name is required').notEmpty();
req.checkBody('email', 'Email is required').notEmpty();
req.checkBody('email', 'Email is not valid').isEmail();
req.checkBody('pass', 'Password is required').notEmpty();
req.checkBody('pass2', 'Passwords do not match.').equals(req.body.pass);
// Check for errors
let errors = req.validationErrors();
if (errors) {
res.render('register', {
errors:errors
});
} else {
// Create new user object
let newUser = new User({
firstname:firstname,
lastname:lastname,
email:email,
pass:pass
});
// Hash the password for security.
bcrypt.genSalt(10, function(err, salt){
bcrypt.hash(newUser.pass, salt, function(err, hash) {
if (err) {
console.log(err);
}
newUser.pass = hash;
newUser.save(function(err) {
if (err) {
console.log(err);
return;
} else {
console.log("Successful creation.")
req.flash('success', 'Account creation successful!');
res.redirect('/users/login');
}
});
});
})
}
});
// Load login form
router.get('/login', function(req, res){
res.render('login');
});
// Submit login form
router.post('/login', function(req, res, next) {
passport.authenticate('local', {
successRedirect: '..',
failureRedirect: '/users/login',
failureFlash: true
})(req, res, next);
});
module.exports = router;
passport.js file
const LocalStrategy = require('passport-local').Strategy;
const passport = require('passport');
const User = require('../models/user');
const config = require('../config/database');
const bcrypt = require('bcryptjs');
// User Authentication
module.exports = function(passport){
console.log("Made it intro str");
passport.use(new LocalStrategy(function(email, pass, done){
// Match username
let query = {email:email};
User.findOne(query, function(error, user){
if (error){
console.log("error");
return done(error);
}
if (!user) {
console.log("No user found");
return done(null, false, {message: 'No user found.'});
}
bcrypt.compare(pass, user.pass, function(error, isMatch) {
if (error) {
console.log("error2");
return done(error);
}
if (isMatch) {
console.log("Matching password");
return done(null, user);
} else {
console.log("Wrong password");
return done(null, false, {message: 'Invalid password.'});
}
});
});
}));
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
User.findById(id, function(err, user) {
done(err, user);
});
});
}
App.js
const createError = require('http-errors');
const express = require('express');
const path = require('path');
const logger = require('morgan');
const session = require('express-session');
const bodyParser = require('body-parser');
const mongoose = require('mongoose');
const expressValidator = require('express-validator');
const config = require('./config/database');
const flash = require('connect-flash');
const passport = require('passport');
/* Connect to Database */
mongoose.connect(config.database, { useNewUrlParser: true });
let db = mongoose.connection;
// Check connection.
db.once('open', function(){
console.log('Connected to MongoDB.');
})
// Check DB error.
db.on('error', function(error){
console.log(error);
});
/* Initialize app */
var app = express();
/* Bring in models for database */
let User = require('./models/user');
// Body Parser Middleware
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
// Load the view engines
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
// Set public folder
app.use(express.static(path.join(__dirname, 'public')));
app.use(expressValidator());
// Keep users session
app.use(session({
secret: 'secret',
resave: true,
saveUninitialized: true,
cookie: { maxAge: 60000 }
}));
app.use(require('connect-flash')());
app.use(function (req, res, next) {
res.locals.messages = require('express-messages')(req, res);
next();
});
// Express Validator Middleware
app.use(expressValidator({
errorFormatter: function(param, msg, value) {
var namespace = param.split('.')
, root = namespace.shift()
, formParam = root;
while(namespace.length) {
formParam += '[' + namespace.shift() + ']';
}
return {
param : formParam,
msg : msg,
value : value
};
}
}));
// Passport config
require('./config/passport')(passport);
app.use(passport.initialize());
app.use(passport.session());
// Load homepage
app.get('/', function(req, res) {
res.render('index', {
title: 'Index',
})
})
// Define routes
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/user');
app.use('/', indexRouter);
app.use('/users', usersRouter)
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
;
module.exports = app;
I believe the issue is in your passport.js file... By default, LocalStrategy expects to find credentials in parameters named username and password. You need to change that... something like so:
const localOptions = { usernameField: 'email', passwordField: 'pass' };
passport.use(new LocalStrategy(localOptions, function (email, pass, done) {
// Match username
let query = { email: email };
User.findOne(query, function (error, user) {
// etc etc...
});
}));
Link to the docs (at the bottom of the page...): http://www.passportjs.org/docs/username-password/
Related
I've been running through a problem and I can not find out what it is. I am using Express for this.
I have an "addUser" form which has the following Pug form :
form(action='/adduser', method='POST')
and I have try POST method in the app.js that doesn't work :
app.post("/adduser", function (req, res, info, next){
console.log('This does not appear');
});
What I don't understand is why the following login POST method which is just right above the adduser works perfectly :
app.post("/login", passport.authenticate('local', {
// login things
});
NB : At the beginning, the /adduser was in a router and was also returning 404, that's why I tried to move it in app.js .
Feel free to ask any informations that you need.
Anthony.
FULL CODE
app.js:
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var escape = require('escape-html');
var stock = require('./routes/stock');
var app = express();
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
// Variables pour le système d'users
var flash = require('connect-flash');
var crypto = require('crypto');
/* Login script */
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var connection = require('./lib/dbconn');
var sess = require('express-session');
var Store = require('express-session').Store;
var BetterMemoryStore = require(__dirname + '/memory');
var store = new BetterMemoryStore({expires: 60 * 60, debug: true});
app.use(sess({
name: 'StockInfo Sess.',
secret: 'C3ci3stUnSup3rS3cr3t',
store: store,
resave: true,
saveUninitialized: true
}));
//======================================================================================================================
// Configs =============================================================================================================
//======================================================================================================================
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use(flash());
app.use(passport.initialize());
app.use(passport.session());
app.use('/stock', stock);
//passport Strategy -- the express session middleware before calling passport.session()
passport.use('local', new LocalStrategy({
usernameField: 'username',
passwordField: 'password',
passReqToCallback: true //passback entire req to call back
}, function (req, username, password, done) {
if (!username || !password) {
return done(null, false, req.flash('message', 'All fields are required.'));
}
var escapeData = escape(username);
var comboPrenomNom = escapeData.split(".");
var prenom = comboPrenomNom[0].toLowerCase();
var nom = comboPrenomNom[1].toLowerCase();
connection.query("SELECT id, password, salt FROM users WHERE prenom = ? and nom = ?", [prenom, nom], function (err, rows) {
if (err) return done(req.flash('message', err));
if (!rows.length) {
return done(null, false, req.flash('message', 'Invalid username or password.'));
}
if (!(rows[0].password === crypto.createHash('sha256').update(rows[0].salt + escape(password)).digest('hex'))) {
return done(null, false, req.flash('message', 'Invalid username or password.'));
}
req.session.user = rows[0].id;
return done(null, rows[0].id);
});
}
));
passport.serializeUser(function (id, done) {
done(null, id);
});
passport.deserializeUser(function (id, done) {
connection.query("SELECT id, prenom, nom, hasChangedPass, rights FROM users WHERE id = " + id, function (err, rows) {
done(err, rows[0]);
});
});
//======================================================================================================================
// Routes ==============================================================================================================
//======================================================================================================================
app.get('/', function (req, res, next) {
res.redirect('/login');
});
app.get('/login', function (req, res) {
res.render('login/index', {
title: 'LogIn',
message: req.flash('message')
});
});
app.post("/login", passport.authenticate('local', {
successRedirect: '/stock',
failureRedirect: '/login',
failureFlash: true
}), function (req, res, info) {
res.render('login/index', {
'message': req.flash('message')
});
});
app.post("/adduser", function (req, res, info, next) {
if (req.body.prenom && req.body.nom && req.body.password) {
var prenom = escape(req.body.prenom).toLowerCase();
var nom = escape(req.body.nom).toLowerCase();
connection.query("SELECT * FROM users WHERE prenom = ? and nom = ?", [prenom, nom], function (err, rows) {
if (err) {
console.log(err);
}
if (!rows.length) {
var salt = generate_token(32);
var password = escape(req.body.password);
password = crypto.createHash('sha256').update(salt + '' + password).digest('hex');
connection.query("INSERT INTO users (prenom, nom, password, salt) VALUES (?, ?, ?, ?);", [prenom, nom, password, salt], function (err) {
if (err) {
console.log(err);
}
});
}
});
} else {
res.redirect('/stock/fromage');
}
});
app.get('/logout', function (req, res) {
req.session.destroy();
req.logout();
res.redirect('/login');
});
// 404
app.use(function (req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handler
app.use(function (err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error', {title: err.status});
});
function hasRights(req, res, next) {
if (req.user.rights[0] == 1 || req.user.rights[1] == 2 || req.user.rights[2] == 2 || req.user.rights[3] == 2) {
return next();
}
res.redirect('/stock');
}
function isAuthenticated(req, res, next) {
if (req.session.user) {
if (req.user.hasChangedPass) {
return next();
} else {
res.redirect('/stock/initpass');
}
}
res.redirect('/login');
}
module.exports = app;
/login/register.pug
extends ../layout
block content
include ../templates/header
.wrapper
form(action='/adduser', method='POST')
h3 Nouvel utilisateur
div.form-row
div.form-group
input.form-control(type='text', placeholder='Prénom', name='prenom' required)
div.form-row
div.form-group
input.form-control(type='text', placeholder='Nom', name='nom' required)
div.form-row
div.form-group
input.form-control(type='text', placeholder='Mot de Passe', name='password', value= pass required)
div.form-row
div.form-group
button.form-control Créer
div.form-row
div.form-group
p= rights
In your /adduser route you have 4 parameters in the callback function: (req, res, info, next). Remove info and Express will find your route.
With four parameters Express interprets your handler function as an error handler, see more information here: https://expressjs.com/en/guide/error-handling.html. Because of that you get a 404, as the request is passed through the middleware chain into the 404 handler.
I am trying to make a signup and signin app in node.js. I am using passport.js for authentication purpose.
My main problem here is whenever i submit my signup form with valid form data, its automatically log user in. Other functions are working properly. Login works perfectly but whenever i submit signup form it submits without any errors and shows successful message too. But main drawback is along with singup it also log user in which i don`t want.
Here is my code
app.js
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
const validator = require('express-validator');
const passport = require('passport');
const expressHbs = require('express-handlebars');
const flash = require('connect-flash');
const session = require('express-session');
const mongoose = require('mongoose');
const configDB = require('./config/database.js');
//db configuration
mongoose.connect(configDB.url, (err) => {
if(err) {
console.log('Error connecting to databse');
} else {
console.log('Connection Successful');
}
});
require('./config/passport');
var index = require('./routes/index');
var users = require('./routes/users');
var app = express();
// view engine setup
app.engine('.hbs', expressHbs({defaultLayout: 'layout', extname: '.hbs'}));
app.set('view engine', '.hbs');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(validator());
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use(express.static(path.join(__dirname, 'node_modules')));
//required for passport
app.use(session({
secret: 'mysecret',
resave: false,
saveUninitialized: false
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(flash());
app.use((req, res, next) => {
res.locals.login = req.isAuthenticated();
res.locals.session = req.session;
next();
});
app.use('/users', users);
app.use('/', index);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
passport.js
const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;
const User = require('../models/user');
passport.serializeUser((user, done) => {
done(null, user.id);
});
passport.deserializeUser((id, done) => {
User.findById(id, (err, user) => {
done(err, user);
});
});
passport.use('local-signup', new LocalStrategy({
usernameField: 'email',
passwordField: 'password',
passReqToCallback: true
}, (req, email, password, done) => {
var fullname = req.body.name;
var address = req.body.address;
req.checkBody('name', 'Name is Required').notEmpty();
req.checkBody('email', 'Invalid email').notEmpty().isEmail();
req.checkBody('password', 'Invalid password').notEmpty().isLength({ min: 4 });
var errors = req.validationErrors();
if (errors) {
var messages = [];
errors.forEach((error) => {
messages.push(error.msg);
});
return done(null, false, req.flash('error', messages));
}
User.findOne({ 'email': email }, (err, user) => {
if (err) {
return done(err);
}
if (user) {
return done(null, false, {message: 'That email is already taken.'});
} else {
var newUser = new User();
newUser.fullname = fullname;
newUser.email = email;
newUser.password = newUser.encryptPassword(password);
newUser.address = address;
newUser.isAdmin = false;
//saving the user
newUser.save((err) => {
if (err) {
return done(err);
}
return done(null, newUser, req.flash('info', 'Signup Completed, pleases login to continue'));
});
}
});
}));
passport.use('local-signin', new LocalStrategy({
usernameField: 'email',
passwordField: 'password',
passReqToCallback: true
}, (req, email, password, done) =>{
req.checkBody('email', 'Invalid email').notEmpty().isEmail();
req.checkBody('password', 'Invalid password').notEmpty().isLength({ min: 4 });
var errors = req.validationErrors();
if (errors) {
var messages = [];
errors.forEach((error) => {
messages.push(error.msg);
});
return done(null, false, req.flash('error', messages));
}
User.findOne({'email': email}, (err, user) => {
if(err) {
return done(err);
}
if(!user) {
return done(null, false, {message: 'No User Found'});
}
if(!user.validPassword(password)) {
return done(null, false, {message: "Wrong Password"});
}
return done(null, user);
});
}));
user.js
var express = require('express');
var router = express.Router();
const passport = require('passport');
const User = require('../models/user');
/* GET users listing. */
router.get('/admin/dashboard', isLoggedIn, isAdmin, (req, res) => {
var user = req.user;
User.find({}, (err, users) => {
if(err) {
throw err;
} else {
res.render('admin/dashboard', {
successMsg: 'Hello' + ' ' + user.fullname,
users: users
});
}
});
});
//router.use('/', notLoggedIn, (req, res, next) => {
// next();
//});
router.get('/login', (req, res) => {
var messages = req.flash('error');
var infoMsg = req.flash('info');
res.render('users/login', { infoMsg: infoMsg, messages: messages, hasErrors: messages.length > 0 });
});
router.post('/login', passport.authenticate('local-signin', {// successRedirect: '/users/profile',
failureRedirect: '/users/login',
failureFlash: true
}), (req, res, next) => {
user = req.user;
role = user.isAdmin;
if(role) {
return res.redirect('/users/admin/dashboard');
} else {
return res.redirect('/users/profile');
}
});
router.get('/signup', (req, res, next) => {
var messages = req.flash('error');
res.render('users/signup', { messages: messages, hasErrors: messages.length > 0 });
});
router.post('/signup', passport.authenticate('local-signup', {
successRedirect: '/users/login',
failureRedirect: '/users/signup',
failureFlash: true
}));
router.get('/profile', isLoggedIn, (req, res) => {
var user = req.user;
var role = user.isAdmin;
res.render('users/profile', {
user: user,
role: role,
successMsg: 'Welcome' + ' ' + user.fullname
});
});
router.get('/logout', isLoggedIn, (req, res, next) => {
req.logout();
res.redirect('/users/login');
});
//route middleware to make sure a use is logged in
function isLoggedIn(req, res, next) {
//if user is authenticated in the session, carry on
if(req.isAuthenticated()) {
return next();
}
res.redirect('/users/login');
}
function isAdmin(req, res, next) {
var user = req.user;
if(user.isAdmin == true) {
return next();
}
res.redirect('/users/profile');
}
function notLoggedIn(req, res, next) {
if(!req.isAuthenticated()) {
return next();
}
res.redirect('/');
}
module.exports = router;
You can use session configuration as per passport documentation
.post(passport.authenticate('local-signup', {
successRedirect: '/users/login',
failureRedirect: '/users/signup',
badRequestMessage: "You must fill in all of the form fields.",
failureFlash: true, // allow flash,
session: false // prevent auto-login
})
or you can give a callback to passport call and prevent session storing so it will not perform login
router.post('/signup', function(req, res, next) {
passport.authenticate('local-signup', function(err, user) {
if (err) { return next(err) }
if (!user) { return res.redirect('/users/signup') }
res.redirect('/users/login');
})(req, res, next);
});
I try to implement a register on my web app, using Node JS and Passport.js for local authentication, but I have this error when I Post the request on Insomnia (Like Postman) :
Bad Request
I don't understand because I have follow a tutorial that I find on Google to do this.
Here is the route (auth.js):
const passport = require('passport');
const router = require('express').Router();
//const UserController = require('../controller/UserController');
router
// login
.post("/login", passport.authenticate("local", function(req, res, next) {
console.log(req);
}))
// logout
.get('/logout', (req, res, next) => {
req.session.destroy((err) => {
res.redirect('/login')
})
})
// signup
.post("/signup", passport.authenticate("local-register"), (req, res) => {
var userInfo = req.body;
})
module.exports = router;
Here is Passport.js file :
const bcrypt = require('bcrypt-nodejs');
const db = require("./queries");
const passport = require('passport');
const LocalStrategy = require("passport-local").Strategy
passport.use(new LocalStrategy(authenticate))
passport.use("local-register", new LocalStrategy({passReqToCallback: false}, register))
function authenticate(email, password, done) {
db.one('select * from users where email = $1', email)
.then((user) => {
if(!user || !bcrypt.compareSync(password, user.password)) {
return done(null, false, {message: "invalid user and password combination"});
}
done(null, user)
}, done);
}
function register(email, password, done) {
db.one('select * from users where email = $1', email)
.then((user) => {
if(user) {
return done(null, false, {message: "An user with this address have already been created."});
}
const newUser = {
email: email,
password: bcrypt.hashSync(password),
};
db.none('insert into users(email, password) values($1, $2)', [newUser.email, newUser.password])
.then((ids) => {
newUser.id = ids[0]
done(null, newUser)
})
})
}
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
db.one('select * from users where id = $1', id)
.then((user) => {
done(null, user)
}, done);
});
I'm using Postgresql as DB for this project, with pg-promise package.
And this is the app.js file :
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var session = require('express-session');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var passport = require('passport')
require('./passport');
var index = require('./routes/index');
var usersRoutes = require('./routes/users');
var authRoutes = require('./routes/auth');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use(passport.initialize())
app.use(passport.session())
app.use('/', index);
app.use(usersRoutes);
app.use(authRoutes);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
Doest anyone know why I have this response ? I try with a post method using email and password on Insomnia,
Thank you !
By default, LocalStrategy expects to find credentials in parameters named username and password. (passport-local on Github).
So you need to edit this line and set usernameField to email
passport.use("local-register", new LocalStrategy({passReqToCallback: false, usernameField: 'email'}, register))
In your passport.js file on line 4, ensure you end your line ;
const LocalStrategy = require('passport-local');
You can authenticate your details individually as well
passport.use(new LocalStrategy((email, password, done) => {
User.getUserByEmail(email, (err, email) => {
if(err) throw err;
if(!email){
return done(null, false, {message: 'Incorrect Username/Email'});
}
User.comparePassword(password, user.password, (err, isMatch)=>{
if(err) return done(err);
if(isMatch){
return done(null, email);
} else {
return done(null, false, {message: 'Invalid Password'});
}
});
})
}));
Try to stick to one way of writing your code, either ES6 or ES5. And when using ES6, I will advise you use 'use strict' to help you thoroughly check your codes for error.
Im using Node.js and passport, but for some reason i cant seem to access the passport.initialize function. it was working in another file but when i tried to use it on another project (the files below) wont work properly.
i add the relevant files.
server.js
const express = require('express');
const mongoose = require('mongoose');
const port = process.env.PORT || 3000;
const morgan = require('morgan');
const bodyParser = require('body-parser');
const methodOverride = require('method-override');
const app = express();
const authRoutes = require('./app/authRoutes.js');
mongoose.connect("mongodb://localhost/MeanMapApp");
const passport = require('./app/passport');
app.use(passport.initialize());
require('./app/routes.js')(app);
app.listen(port);
console.log('App listening on port ' + port);
passport.js
const passport = require('passport');
const request = require('request');
const LocalStrategy = require('passport-local').Strategy;
const User = require('../models/User');
passport.serializeUser((user, done) => {
done(null, user.id);
});
passport.deserializeUser((id, done) => {
User.findById(id, (err, user) => {
done(err, user);
});
});
authRoutes.js
var express = require('express');
const bluebird = require('bluebird');
const crypto = bluebird.promisifyAll(require('crypto'));
const passport = require('passport');
const User = require('../models/User');
/**
* GET /login
* Login page.
*/
exports.getLogin = (req, res) => {
if (req.user) {
return res.redirect('/account');
}
res.render('account/login', {
title: 'Login'
});
};
/**
* POST /login
* Sign in using email and password.
*/
exports.postLogin = (req, res, next) => {
req.assert('email', 'Email is not valid').isEmail();
req.assert('password', 'Password cannot be blank').notEmpty();
req.sanitize('email').normalizeEmail({ remove_dots: false });
const errors = req.validationErrors();
if (errors) {
req.flash('errors', errors);
return res.redirect('/login');
}
passport.authenticate('local', (err, user, info) => {
if (err) { return next(err); }
if (!user) {
req.flash('errors', info);
return res.redirect('/login');
}
req.logIn(user, (err) => {
if (err) { return next(err); }
req.flash('success', { msg: 'Success! You are logged in.' });
res.redirect('/account');
});
})(req, res, next);
};
/**
* GET /logout
* Log out.
*/
exports.logout = (req, res) => {
req.logout();
res.redirect('/');
};
/**
* GET /signup
* Signup page.
*/
exports.getSignup = (req, res) => {
if (req.user) {
return res.redirect('/account');
}
res.render('account/signup', {
title: 'Create Account'
});
};
/**
* POST /signup
* Create a new local account.
*/
exports.postSignup = (req, res, next) => {
req.assert('email', 'Email is not valid').isEmail();
req.assert('password', 'Password must be at least 4 characters long').len(4);
req.assert('confirmPassword', 'Passwords do not match').equals(req.body.password);
req.sanitize('email').normalizeEmail({ remove_dots: false });
const errors = req.validationErrors();
if (errors) {
req.flash('errors', errors);
return res.redirect('/signup');
}
const user = new User({
email: req.body.email,
password: req.body.password
});
User.findOne({ email: req.body.email }, (err, existingUser) => {
if (err) { return next(err); }
if (existingUser) {
req.flash('errors', { msg: 'Account with that email address already exists.' });
return res.redirect('/signup');
}
user.save((err) => {
if (err) { return next(err); }
req.logIn(user, (err) => {
if (err) {
return next(err);
}
res.redirect('/account');
});
});
});
};
I believe you are doing this the wrong way,instead of
const passport = require('./app/passport');
app.use(passport.initialize());
You should be using
var passport = require('passport');
require('./app/passport');
app.use(passport.initialize());
That should solve it
I'm using ExpressJS + TS and the following returned the same error.
import * as passport from 'passport';
app.use(passport.initialize());
However, this worked
import { initialize } from 'passport';
app.use(initialize());
Not sure why this is happening in the ExpressJS app with TS. I also have the first way implemented on a Google Cloud Function with TS and it works fine.
I also get the same err in the VS code hope it will help you
hello! Buddy everything you write correct but some normal syntax err. it's hard to find
here is my code that helps you to implement the authentication
just I used var at the place of Const
app.js code
var express= require("express");
var mongoose=require("mongoose");
var passport = require('passport');
var bodyParser=require("body-parser");
var User = require("./models/user");
var localStrategy=require("passport-local").Strategy;
var passportLocalMongoose=require("passport-local-mongoose");
mongoose.connect("mongodb://localhost/auth_demo_app",{ useNewUrlParser: true , useUnifiedTopology: true});
var app=express();
app.set("view engine" ,"ejs");
app.use(bodyParser.urlencoded({extended:true}));
app.use(require("express-session")({
secret:"login",
resave :false,
saveUninitialized:false
}));
app.use(passport.initialize());
app.use(passport.session());
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());
//=============================================================
//routes
app.get("/",function(req,res){
res.render("home");
});
app.get("/secret",function(req,res){
res.render("secret");
});
//Auth routes============
//show form
app.get("/register",function(req,res){
res.render("register");
});
//heandling User Sign UP
app.post("/register",function(req,res){
req.body.username
req.body.password
User.register(new User({username : req.body.username}),req.body.password,function(err,user){
if(err){
console.log(err);
return res.render("register");
}
passport.authenticate("local")(req,res,function(){
res.redirect("/secret");
})
});
});
app.listen(8080,function(){
console.log("here i am");
});
you can change your local port
Do some changes as par your requirement and you good to go
I saw a couple of post with similar to mine but I still getting the same error
here is my user schema
var mongoose = require('mongoose');
var bcrypt = require('bcrypt-nodejs');
var userSchema = mongoose.Schema({
local: {
email: String,
password: String,
},
});
userSchema.methods.generateHash = function(password) {
return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null);
};
userSchema.methods.validPassword = function(password) {
return bcrypt.compareSync(password, this.local.password);
};
module.exports = mongoose.model('User', userSchema);
my routes
var express = require('express');
var passport = require('passport');
var router = express.Router();
router.get('/', function(req, res, next) {
res.render('index', { title: 'Express' });
});
router.get('/login', function(req, res, next) {
res.render('login.ejs', { message: req.flash('loginMessage') });
});
router.get('/signup', function(req, res) {
res.render('signup.ejs', { message: req.flash('loginMessage') });
});
router.get('/profile', isLoggedIn, function(req, res) {
res.render('profile.ejs', { user: req.user });
});
router.get('/logout', function(req, res) {
req.logout();
res.redirect('/');
});
router.post('/signup', passport.authenticate('local-signup', {
successRedirect: '/profile',
failureRedirect: '/signup',
failureFlash: true,
}));
router.post('/login', passport.authenticate('local-login', {
successRedirect: '/profile',
failureRedirect: '/login',
failureFlash: true,
}));
module.exports = router;
function isLoggedIn(req, res, next) {
if (req.isAuthenticated())
return next();
res.redirect('/');
}
my app.js
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var mongoose = require('mongoose');
var flash = require('connect-flash');
var session = require('express-session');
var routes = require('./routes/index');
var users = require('./routes/users');
var configDB = require('./config/database.js');
mongoose.connect(configDB.url);
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use(session({ secret: 'shhsecret' }));
app.use(passport.initialize());
app.use(passport.session());
app.use(flash());
require('./config/passport')(passport);
app.use('/', routes);
app.use('/users', users);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handlers
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
});
});
}
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});
module.exports = app;
And here is my passport.js Im using local passport
var LocalStrategy = require('passport-local').Strategy;
var User = require('../models/user');
module.exports = function(passport) {
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
User.findById(id, function(err, user) {
done(err, user);
});
});
passport.use('local-signup', new LocalStrategy({
usernameField: 'email',
passwordField: 'password',
passReqToCallback: true,
},
function(req, email, password, done) {
process.nextTick(function() {
User.findOne({ 'local.email': email }, function(err, user) {
if (err)
return done(err);
if (user) {
return done(null, false, req.flash('signupMessage', 'That email is already in use.'));
} else {
var newUser = new User();
newUser.local.email = email;
newUser.local.password = newUser.generateHash(password);
newUser.save(function(err) {
if (err)
throw err;
return done(null, newUser);
});
}
});
});
}));
passport.use('local-login', new LocalStrategy({
usernameField: 'email',
passwordField: 'password',
passReqToCallback: true,
},
function(req, email, password, done) {
User.findOne({ 'local.email': email }, function(err, user) {
if (err)
return done(err);
if (!user)
return done(null, false, req.flash('loginMessage', 'No user found.'));
if (!user.validPassword(password))
return done(null, false, req.flash('loginMessage', 'Wrong password.'));
return done(null, user);
});
}));
};
passport works it save the user to the database
expressauth 5 > db.users.find()
{ "_id" : ObjectId("586cc8b3ea780c071bbe2469"), "local" : { "password" : "$2a$08$vANw7GJIk8RUVEpJWnwSpOVQ77RuHCjbXiGoQVl.Fx/thhbMkEVWu", "email" : "david#david.com" }, "__v" : 0 }
expressauth 6 >
Cast to ObjectId failed for value “586cc8b3ea780c071bbe2469” at path “_id” for model “User”
I have built a couple apps that use passport oauth the exact same way that I have displayed above. So I dont know why Im getting this error.
Any suggestions?
I had the same problem with mongoose version > 4.7.2
Problem is about bson package.
I solved it with installing an older version of mongoose.
npm install mongoose#4.7.2
or you can change package.json to use exact version 4.7.2 "mongoose": "4.7.2"
You can update to newer versions after the problem is solved. You can track it on here.
The error exists in your serializeUser function in passport.
You need to use user._id instead of user.id.
since there is no field as id in your UserSchema, user.id will beundefined, and while deserializing the user, undefined is not typeOf ObjectId, thus it is throwing above error.
Try this:
passport.serializeUser(function(user, done) {
done(null, user._id);
});
Update:
Do this in your deserializeUser:
cast the upcoming id to ObjectId, just to be sure, and then use that ID to query the User.
var userId = mongoose.Schema.Types.ObjectId(id);
User.findById(userId , function(err, user) {
done(err, user);
});
Dont forget to include mongoose in the same file.
var mongoose=require('mongoose');
Hopefully this will help you.
This is due to latest version of mongoose, you have to use findOneAndRemove instead of FindByIdAndRemove.
That is cast objectId problem.