I have some trouble implementing passport-local on my NodeJS application. I don't understand what I'm doing wrong here. I'll list the important code for this question here.
app.js:
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(passport.initialize());
app.use(passport.session());
users.js:
var express = require('express');
var router = express.Router();
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var User = require('../models/user.js');
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
User.getUserById(id, function(err, user) {
done(err, user);
});
});
passport.use(new LocalStrategy(
function(username, password, done) {
console.log('Entered passport'); // This doesn't even happen
User.getUserByUsername(username, function(err, user) {
if (err) throw err;
if (!user) {
console.log('Unknown 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);
}
console.log('Invalid Password');
return done(null, false, {
message: 'Invalid Password'
});
});
return done(null, user);
});
}
));
router.post('/login', passport.authenticate('local', {
successRedirect: '/',
failureRedirect: '/users/login',
failureFlash: 'Invalid username or password'
}), function(req, res) {
console.log("Authentication Successfull!");
req.flash('success', 'You are logged in');
res.redirect('/');
});
user.js (Model):
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) return callback(err);
callback(null, isMatch);
});
}
I'm not getting any syntax errors. In users.js I want to log a message to the console, but it doesn't even get there. The post function on the login gets fired when I just enter a function with a console.log there, but now it seems that it doesn't. It just reloads the page (looks like it). Any help is appreciated.
try to mount session middleware before passport initilized:
var session = require('express-session')
app.use(session({ secret: 'xxxxxxx' }));
app.use(passport.initialize());
app.use(passport.session());
Related
I've tried everything. I went through all of the answers ever answered to questions with the slightest similarity. I'm desperate.
I'm using passport module for my website and successRedirect is not working, while failureRedirect does exactly what it's supposed to do.
this is users.js, it does the routing.
'use strict';
const passport = require('passport');
const User = require('../models/user');
module.exports = function(_, passport){
return {
SetRouting: function(router){
console.log('got it');
router.get('/', this.indexPage);
router.get('/signup', this.getSignUp);
router.get('/home', this.homePage);
router.post('/signup', this.postSignUp);
},
indexPage: function(req, res){
console.log('got index page');
return res.render('index');
},
getSignUp: function(req, res){
console.log('got signup page');
return res.render('signup');
},
homePage: function(req, res){
console.log('got home page');
return res.render('home');
},
postSignUp: passport.authenticate('local.signup', {
successRedirect: '/home',
failureRedirect: '/signup',
failureFlash: true
}),
}
and this is passport-local.js, where I do my local strategy function call:
'use strict';
const passport = require('passport');
const User = require('../models/user');
const LocalStrategy = require('passport-local').Strategy;
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) => {
User.findOne({'email': email}, (err, user) => {
if(err){
return done(err);
}
if(user){
return done(null, false, req.flash('error', 'User with email already exist'));
}
const newUser = new User();
newUser.username = req.body.username;
newUser.fullname = req.body.username;
newUser.email = req.body.email;
newUser.password = newUser.encryptPassword(req.body.password);
newUser.save((err) => {
done(null, newUser);
});
});
}));
i'd appriciate your help so so so much!
Your strategy is named 'local.signup'. Strategy names can't contain a period.
There are a number of places where Passport uses the strategy name as an object key and variable identifier. For example, Passport's Authenticator constructs, and later references, an Object of strategies with the strategy names as keys:
Authenticator.prototype.use = function(name, strategy) {
...
this._strategies[name] = strategy;
return this;
};
For this to work, name must be a valid Javascript identifier, meaning no periods.
Note: there are many similar questions but I've gone through all of them and none of the solutions work.
Hi,
I've tried every solution on the net, bug still persists.
I'm building a simple CRUD app, and I'm currently struggling with passportjs's req.isAuthenticated().
The user is definitely being authenticated, as console.log(req.user) in passport.authenticate returns the user object, and req.session.passport has the user id.
After the redirect though, even if the redirect is async, user is undefined and req.session.passport is empty. It's as if the session is reset.
Here's the code:
app.js
var express = require('express');
var path = require('path');
var bodyParser = require('body-parser');
var session = require('express-session');
var passport = require('passport');
var flash = require('connect-flash');
var index = require('./routes/index');
var users = require('./routes/users');
var app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: false
}));
app.set('view engine', 'ejs');
app.set('views', path.join(__dirname, 'views'));
app.use(express.static(path.join(__dirname, 'public')));
app.use('/bootstrap', express.static(path.join(__dirname + '/node_modules/bootstrap/dist')));
app.use(session({
secret: 'keyboard cat',
resave: true,
saveUninitialized: true,
cookie: {
maxAge: 5 * 60 * 1000
}
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(flash());
app.use(function(req, res, next) {
res.locals.messages = require("express-messages")(req, res);
next();
});
app.get('*', function(req, res, next) {
console.log(req.method, ":", req.url);
res.locals.user = req.user || null;
next();
});
app.use("/", index);
app.use("/users", users);
var port = 4000;
app.listen(port);
module.exports = app;
index.js
var express = require('express');
var router = express.Router();
router.get('/', isLoggedIn, function(req, res) {
if (req.user) {
console.log(req.user.username);
}
res.render('homepage');
});
function isLoggedIn(req, res, next) {
console.log("passport: ", req.session.passport); //passport:{}
if (req.isAuthenticated()) {
return next();
}
res.redirect('/users/login');
}
module.exports = router;
users.js
var express = require('express');
var router = express.Router();
var mongojs = require('mongojs');
var db = mongojs('usersDB', ['users']);
var bcrypt = require('bcryptjs');
var passport = require('passport'),
LocalStrategy = require('passport-local').Strategy;
router.get('/login', function(req, res) {
res.render('login');
});
router.get('/signup', function(req, res) {
res.render('signup');
});
router.post('/signup', function(req, res) {
db.users.findOne({
username: req.body.name
}, function(err, user) {
if (err) {
return done(err);
}
if (user) {
console.log("nope");
req.flash("error", "Username taken. Choose a different username.");
return res.redirect('/users/signup');
}
var password = req.body.password;
bcrypt.genSalt(10, function(err, salt) {
if (err) {
return done(err);
}
bcrypt.hash(password, salt, function(err, hash) {
if (err) {
return done(err);
}
var user = {
username: req.body.name,
email: req.body.email,
phone: req.body.phone,
password: hash
}
db.users.insert(user, function(err, result) {
if (err) {
return done(err);
}
console.log("registered", user)
res.render("homepage", {
user: user
});
});
});
});
});
}); //sorry for the callback hell..works fine
passport.serializeUser(function(user, done) {
return done(null, user._id);
});
passport.deserializeUser(function(id, done) {
db.users.findOne({
id: mongojs.ObjectId(id)
}, function(err, user) {
return done(err, user);
});
});
passport.use('loginStrategy', new LocalStrategy({
passReqToCallback: true,
usernameField: 'username',
passwordField: 'password'
},
function(req, username, password, done) {
db.users.findOne({
username: username
}, function(err, user) {
if (err) {
return done(err);
}
if (!user) {
return done(null, false, req.flash('error', "Invalid username."));
}
bcrypt.compare(password, user.password,
function isMatch(err, isMatch) {
if (err) {
return done(err);
}
if (!isMatch) {
return done(null, false, req.flash('error', "Oops. Incorrect password."));
}
return done(null, user, req.flash('success', "Welcome " + user.username + ", you are now logged in."));
});
});
}));
router.post('/login', function(req, res, next) {
passport.authenticate('loginStrategy', function(err, user, info) {
if (info) {
req.flash('error', info.message);
}
if (err) {
return next(err);
}
if (!user) {
return res.redirect('/users/login');
}
req.logIn(user, function(err) {
if (err) {
return next(err);
}
//callback redirect after saving session.
req.session.save(function() {
console.log(req.session.passport); //{ user: 59ceb263dae7a4270087ae57 }
res.redirect('/');
});
});
})(req, res, next);
});
router.get('/logout', function(req, res) {
req.logout();
res.redirect('/users/login');
});
module.exports = router;
I would really appreciate some help, as this is seems to be a common bug, but none of the workarounds work for me.
This seems to be related to the method you are using to store the user creds. Please note, Chrome and IE have different quirks about local vs session storage. Try this in chrome, Passport JS will store the response in either Local or Session storage - you should interrogate those storage mechanisms to verify the user's credentials are in them.
In chrome, go to the F12 debug tools and look in your session and local storage:
Please let us know the browser you are using, and if using Chrome makes a difference.
Hello SO wonderful users
I am having trouble with passport js since two days and cant figure it out.
Passport Strategy is not being called.
the console.log is not being called!
any ideas ?
here is my code
//init.js
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
module.exports = function(app) {
passport.use(new LocalStrategy(function(username, password, done) {
console.log(username, password);
return done(null, {username: 'agent'});
}));
passport.serializeUser(function(user, done) {
done(null, 'agent');
});
passport.deserializeUser(function(id, done) {
done(null, {username: 'agent'});
});
app.use(passport.initialize());
};
//routes.js
var passport = require('passport');
module.exports = function(app) {
app.get('/login', function(req, res) {
res.send('login');
});
app.post('/login', function(req, res, next) {
passport.authenticate('local', function(err, user, info) {
if (err) {
return next(err);
}
if (!user) {
console.log(user);
console.log('no user');
return res.redirect('/login');
}
req.logIn(user, function(err) {
if (err) {
return next(err);
}
return res.redirect('/');
});
})(req, res, next);
});
//index.js, where i call the auth
require('./src/auth/init')(app);
require('./src/auth/routes')(app);
edit
solution
the issue was with postman, I hade to change the body post data to x-www-form-urlencoded
im working on a node passport login authentication but im stack on this error which makes it hard for me to run my node server
/home/emil/Documents/myapp/app/routes.js:14
app.post('/login', passport.authenticate('local-login', {
^
TypeError: Cannot read property 'authenticate' of undefined
how can i fix it?
my code:
server.js
var express = require('express');
var app = express();
var port = 8080;
var cookieParser = require('cookie-parser');
var session = require('express-session');
var morgan = require('morgan');
var mongoose = require('mongoose');
var bodyParser = require('body-parser');
var passport = require('passport');
var configDB = require('./config/database.js');
mongoose.connect(configDB.url);
app.use(passport.initialize());
app.use(passport.session());
app.use(morgan('dev'));
app.use(cookieParser());
app.use(bodyParser.urlencoded({
extended: false
}));
app.use(session({
secret: 'anystringoftext',
saveUninitialized: true,
resave: true
}));
app.set('view engine', 'ejs');
//app.use('/', function(req, res){
// res.send('Our First Express program!');
// console.log(req.cookies);
// console.log('===============');
// console.log(req.session);
//});
require('./app/routes.js')(app);
app.listen(port);
console.log('Server running on port: ' + port);
routes.js:
var User = require('./models/user');
module.exports = function (app, passport) {
app.get('/', function (req, res) {
res.render('index.ejs');
});
app.get('/login', function (req, res) {
res.render('login.ejs', {
message: req.flash('loginMessage')
});
});
app.post('/login', passport.authenticate('local-login', {
successRedirect: '/profile',
failureRedirect: '/login',
failureFlash: true
}));
app.get('/signup', function (req, res) {
res.render('signup.ejs', {
message: req.flash('signupMessage')
});
});
app.post('/signup', passport.authenticate('local-signup', {
successRedirect: '/',
failureRedirect: '/signup',
failureFlash: true
}));
app.get('/profile', isLoggedIn, function(req, res){
res.render('profile.ejs', { user: req.user });
});
app.get('/:username/:password', function (req, res) {
var newUser = new User();
newUser.local.username = req.params.username;
newUser.local.password = req.params.password;
console.log(newUser.local.username + " " + newUser.local.password);
newUser.save(function (err) {
if (err)
console.log(err);
});
res.send("Success!");
})
};
function isLoggedIn(req, res, next) {
if(req.isAuthenticated()){
return next();
}
res.redirect('/login');
}
passport.js
var LocalStrategy = require('passport-local').Strategy;
var User = require('../app/models/user');
module.exports - function(passport) {
passport.serializeUser(function(usser, 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.username': email}, function(err, user){
if(err)
return done(err);
if(user){
return done(null, false, req.flash('signupMessage', 'That account exists'));
} else {
var newUser = new User();
newUser.local.username = email;
newUser.local.password = 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){
process.nextTick(function(){
User.findOne({ 'local.username': email}, function(err, user){
if(err)
return done(err);
if(!user)
return done(null, false, req.flash('loginMessage', 'No user found'));
if(user.local.password != password)
return done(null, false, req.flash('loginMessage', 'invalid password'));
}
return done(null, user);
})
})
}
))
You have not passed passport to the routes. require('./app/routes.js')(app); should be require('./app/routes.js')(app, passport) in server.js;
I have an express app that I am trying to authenticate with passport-local. Here is my express app:
app.use(express.bodyParser());
app.use(express.cookieParser());
app.use(express.session({ secret: 'this is a string' }));
app.use(passport.initialize());
app.use(passport.session());
client = new pg.Client(connectionString);
client.connect();
passport.use(new LocalStrategy(
function(username, password, done) {
var query = client.query('SELECT * FROM users WHERE EMAIL = $1', [username], function(err, result){
if(err) {
console.log("Error");
return done(err);
}
if(!result.rows.length > 0) {
console.log("No users");
return done(null, false, { message: 'User not found'});
}
if(result.rows[0].password !== password) {
console.log("incorrect password");
return done(null, false, { message: 'Password Incorrect'});
}
console.log('authenticated');
return done(null, result.rows[0]);
});
}
));
passport.serializeUser(function(user, done) {
'use strict';
console.log('serialize');
console.log(user);
done(null, user.email);
});
passport.deserializeUser(function(id, done) {
'use strict';
console.log('deserialize');
User.findById(id, function(err, user) {
done(err, user);
});
});
app.post('/login', passport.authenticate('local'), function(req, res) {
'use strict';
console.log(req.user.username);
});
app.listen(port, function() {
'use strict';
console.log('Listening on:', port);
});
I then hit the /login url with this json in my body: {username: 'jason#gmail.com', password: 'password }. I go through the LocalStrategy function and then in the serialize function it makes it to the done function and then just hangs. I get no errors or additional logging, the connection just stays open and control is not given back to the caller. I never receive a http status, it just hangs.
I think it is a problem with my session, but I do not understand what to do next?
Ok, could you try a redirect there? It looks like your session / auth is ok, if you get a proper username at that point.
app.post('/login', passport.authenticate('local', {
successRedirect: '/somewhere_intern',
failureRedirect: '/login'
}));