I'm trying to assign the user to a cookie when someone logs in, but looks like passport is not assigning the data to the cookie. Below you can find the code:
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(cookieParser());
app.use(bodyParser.json());
app.use(passport.initialize());
//Use session
app.use(passport.session({ secret: '=Mx;D5F}t&iJZ&w-g;FLK:%QavZgZt', cookie: { maxAge: 0 }, resave: true, saveUninitialized: true }))
app.use(express.static('server/public'));
//Set view engine
app.set('views', 'server/views')
app.set('view engine', 'pug');
//Set passport local strategy
passport.use(new LocalStrategy({ usernameField: "email" },
function (email, password, done) {
User.findOne({ 'email': email }, async function (err, user) {
console.log('user requested password caught in passport: ', password);
if (err) { return done(err); }
if (!user) {
return done(null, false, console.log('Wrong username'));
}
return await user.validatePassword(password, function (err, result) {
if (err || !result) return done(null, false, console.log('Wrong Password'));
return done(null, user);
})
});
}
));
// serialize user object
passport.serializeUser(function (user, done) {
done(null, user.id);
});
// deserialize user object
passport.deserializeUser(function (id, done) {
User.findById(id, function (err, user) {
done(err, user);
})
});
and this is the login route:
//Route for user login
app.post('/auth/local/signin',
function (req, res, next) {
passport.authenticate('local', function (err, user, info) {
console.log(err);
console.log(user);
if (err) {
console.log('passport.authenticate: error')
} else if (!user) {
console.log('passport.authenticate: user')
} else {
console.log('next handler')
console.log('Cookie assigned: ' + req.user)
return res.redirect('/dashboard')
}
return res.redirect('/login')
})(req, res, next)
}
)
As you can see, I have tried to log req.user which is giving me back undefined.
However, the console.log(user) gives me back the user from the DB, which is what I want.
Related
I took a tutorial from the odin project on passport and it worked so I decided to implement what I learned on my own project, the difference between theirs and mine is that I was following a design pattern while they weren't and I can't seem to find the problem as to why it is not responding .
in my login page I use the email and password and I've tried changing the below code many times.
this is the controller.js
//passport functions
passport.use(
new LocalStrategy((username, password, done) => {
User.findOne({ username: username }, (err, user) => {
console.log(user)
if (err) {
return done(err);
};
if (!user) {
return done(null, false, { msg: "Incorrect username" });
}
if (user.password !== password) {
return done(null, false, { msg: "Incorrect password" });
}
return done(null, user);
});
})
);
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
User.findById(id, function(err, user) {
done(err, user);
});
});
//end ofpassport functions
app.use(session({ secret: "cats",
resave: false, saveUninitialized: true }));
app.use(passport.initialize());
app.use(passport.session());
app.use(express.urlencoded({ extended: false }));
app.use(function(req, res, next) {
res.locals.currentUser = req.user;
next();
});
I then called the controller from the routes.js to authenticate the user yet it keeps failing and defaulting on the failredirecting
app.post('/signin', passport.authenticate("local",{
successRedirect:"/",
failureRedirect:'/signup'}))
By default, LocalStrategy expects to find credentials in parameters named username and password. If your site prefers to name these fields differently, options are available to change the defaults.
name of parameters in req.body should match with custom fields and LocalStrategy not called when there are empty fields usernameField and passwordField
const customFields = {
usernameField : "email",
passwordField : "password"
}
passport.use(
new LocalStrategy(customFields ,(username, password, done) => {
User.findOne({ username: username }, (err, user) => {
console.log(user)
if (err) {
return done(err);
};
if (!user) {
return done(null, false, { msg: "Incorrect username" });
}
if (user.password !== password) {
return done(null, false, { msg: "Incorrect password" });
}
return done(null, user);
});
})
);
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
User.findById(id, function(err, user) {
done(err, user);
});
});
//end ofpassport functions
app.use(session({ secret: "cats",
resave: false, saveUninitialized: true }));
app.use(passport.initialize());
app.use(passport.session());
app.use(express.urlencoded({ extended: false }));
app.use(function(req, res, next) {
res.locals.currentUser = req.user;
next();
});
Below is my registration strategy in passportJS. Most of the code runs fine until right at the bottom where I go to res.send the user argument after the passport.authenticate method has successfully authenticated the strategy. However whenever I am sent back the response I receive a page with a "false" message. Instead of sending me the users details I am sent "false" instead.
app.use(passport.initialize());
app.use(passport.session());
passport.serializeUser(function(user, done) {
return done(null, user.id);
});
passport.deserializeUser(function(id, done) {
User.findById(id, function(err, user) {
done(err, user);
});
});
passport.use("registerUser",
new LocalStrategy({ passReqToCallback: true },
function(req, username, password, done) {
var newUser = new User({
name: username,
email: req.body.email,
password: password
});
newUser.save(function(err) {
if (err) {
return done(err);
}
return done(null, newUser);
});
}));
app.get("/", function(req, res) {
res.render("index", { title: "Register!", url: req.url });
});
app.post("/", function(req, res, next) {
passport.authenticate("registerUser", function(err, user) {
if (err) {
return done(err);
}
res.send(user);
})(req, res, next);
});
You should use passport.authenticate() as a second argument before function(req, res):
`app.post('/', passport.authenticate('registerUser', function(err, user) {
if (err) return done(err);
if (!user) return done(null, false);
done(null, user);
}), function(req, res) {
res.send(user);
});`
This way you introduced authentication middleware that will run before the response. Have a look here: https://github.com/passport/express-4.x-local-example/blob/master/server.js
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());
our passport login worked fine before we added a database.
Now we seem to be saving an ID that is not a facebook ID
it is saving _ID and we cannot retrieve facebook data from our database.
So I am guessing the problem is that it is not saving to the database correctly,
But unsure why.
passport.serializeUser(function(user, done) {
console.log('serializeUser: ' + user.id)
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
console.log(id)
User.findById(id, function(err, user){
console.log(user)
if(!err) done(null, user);
else done(err, null)
})
});
var sessionData = session({
store: sessionStore.createSessionStore(),
secret: "your_secret",
cookie: { maxAge: 2628000000 },
resave: true,
saveUninitialized: true
});
passport.use(new FacebookStrategy({
clientID: FACEBOOK_APP_ID,
clientSecret: FACEBOOK_APP_SECRET,
callbackURL: "/auth/facebook/callback",
profileFields: ['id', 'name'],
enableProof: false
},
function(accessToken, refreshToken, profile, done) {
console.log("accesstoken: " + accessToken + "refreshToken " + refreshToken + "profile: " + profile.id + "done:" + done)
User.findOne({
'facebook.id': profile.id
}, function(err, user) {
if (err) {
return done(err);
}
if (!user) {
user = new User({
facebookID: profile.id,
name: profile.displayName,
provider: 'facebook',
facebook: profile._json
});
user.save(function(err) {
if (err) console.log(err);
return done(err, user);
});
} else {
//found user. Return
return done(err, user);
}
});
}
));
var app = express();
app.set('views', __dirname + '/app/views');
app.set('view engine', 'ejs');
app.use(sessionData);
app.use(logger("combined"));
app.use(cookieParser());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(methodOverride());
app.use(session({
secret: "keyboard cat",
saveUninitialized: true, // (default: true)
resave: true, // (default: true)
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(express.static(__dirname + '/app/public'));
app.use(express.static(__dirname + '/'));
var http = require('http');
server = http.createServer(app);
io = require('socket.io')(server);
app.get('/', function(req, res){
res.render('index', { user: req.user });
});
app.get('/account', ensureAuthenticated, function(req, res){
User.findById(req.session.passport.user, function(err, user) {
if(err) {
console.log(err);
} else {
res.render('account', { user: user});
}
});
});
app.get('/login', function(req, res){
res.render('login', { user: req.user });
});
app.get('/auth/facebook',
passport.authenticate('facebook'));
app.get('/auth/facebook/callback',
passport.authenticate('facebook', { failureRedirect: '/login' }),
function(req, res) {
res.redirect('/');
});
app.get('/logout', function(req, res){
req.logout();
res.redirect('/');
});
Repo is on a branch
https://github.com/5-minute-catchup/ANEWREPO/tree/mongodb
User.findOne({
'facebook.id': profile.id
}
Should be:
User.findOne({
facebookID: profile.id
}
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'
}));