The problem is when I want pass object to view. I got a message user is undefined. The object is defined after if statement is Match and in serializeUser function. I do not know why I lose this object in route to lobby.
Here I post the route code.
var express = require('express');
var router = express.Router();
var User = require('../models/user');
var Facebook = require('../models/facebook');
var passport = require('passport')
var LocalStrategy = require('passport-local').Strategy;
var FacebookStrategy = require('passport-facebook').Strategy;
router.get('/lobby', function(req, res){
console.log("User req "+req.user);// here I got the message user undefined and I do not know why
res.render('lobby',{ user:req.user});
// res.render('lobby');
});
router.get('/logout',function(req, res){
req.logout();
req.flash('success_msg', 'You have been logged out');
res.redirect('/');
});
function ensureAuthenticated(req, res, next){
if(req.isAuthenticated()){
return next();
}else{
res.redirect('/');
}
}
router.post('/login', passport.authenticate('local', {
successRedirect : '/users/lobby',
failureRedirect : '/',
failureFlash : true
}));
//Passport strategy
passport.serializeUser(function(user, done) {
console.log("serizlize "+user); //here I got object user and it is defined
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) {
User.getUserByUsername(username, function(err, user){
if(err) throw err;
if(!user){
return done(null, false, {message: 'wrong data'});
}
User.comparePassword(password, user.password, function(err, isMatch){
if(err) throw err;
if(isMatch){
return done(null, user);
}else{
return done(null, false,{message: 'wrong data'});
}
});
});
}));
module.exports = router;
enter link description here
*******Edit*****
Problem solved. I just red that you have to initalize express session before passport session. That works for me.
In your server file (my is app.js)
//express session
app.use(session({
secret: 'yoursecrethere',
saveUninitialized: true,
resave: false
}));
//Passport init
app.use(passport.initialize());
app.use(passport.session());
Related
I have a server set up to authenticate user login, so far I was able to successfully authenticate user and redirect them to the success page (as well as redirect them back to the login page if failed). However, I can't use my own express middleware to restrict user if they are not logged in, for some reason my req.isAuthenticate() check in the middleware is always false. I feel like my session info is not stored when logging in, but I'm not sure.
Here's my setup (note that I use express-flash-2 instead of connect-flash therefore the req.flash())
In server.js
// ...
var flash = require('express-flash-2');
var session = require('express-session');
var passport = require('passport');
// ...
server.use(session({
secret: 'keyboard cat',
resave: true,
saveUninitialized: true
}));
server.use(flash());
server.use(passport.initialize());
server.use(passport.session());
passport.use(auth_controller.authStrategy);
passport.serializeUser(auth_controller.authSerializer);
passport.deserializeUser(auth_controller.authDeserializer);
server.get('/maintenance_login', (req, res) => {
res.render('login');
});
server.post('/maintenance_login', passport.authenticate('local', {
successRedirect: '/maintenance',
failureRedirect: '/maintenance_login',
failureFlash: true
}));
// This does basically the same as above
// server.post('/maintenance_login', (req, res, next) => {
// passport.authenticate('local', function(err, user, info) {
// if (err) { return next(err); }
// if (!user) { return res.redirect('/maintenance_login'); }
//
// req.logIn(user, function(err) {
// if (err) { return next(err); }
// console.log('is authenticated?: ' + req.user); // this returns true
// return res.redirect('/maintenance');
// });
// })(req, res, next);
// });
server.get('/maintenance:query?', auth_controller.restrict, maintenance_controller.maintenance_list);
In auth_controller.js
var passport = require('passport');
var LocalStrategy = require('passport-local');
var User = require('../models/user');
exports.authStrategy = new LocalStrategy({
usernameField: 'email',
passwordField: 'password'
}, function (email, password, done) {
User.authenticate(email, password, function(err, user) {
// success message
// error message
done(err, user, err ? { message: err.message } : null);
});
});
exports.authSerializer = function(user, done) {
done(null, user.id);
};
exports.authDeserializer = function(id, done) {
User.findById(id, function(err, user) {
done(err, user);
});
};
exports.restrict = function (req, res, next) {
console.log('is authenticated?: ' + req.isAuthenticated()); // This always returns false
if (req.isUnauthenticated()) {
res.flash('error', 'Access denied, please log in.');
return res.redirect('/maintenance_login');
}
return next();
}
Again, my issue is that whenever I was successfully logged in, I got kicked back to /maintenance_login and the flash showing "Access denied, please log in.". Which means that req.isUnauthenticated() in the restrict middleware returns true.
Any ideas?
Well, it turns out that missing the .Strategy is crucial. Changing var LocalStrategy = require('passport-local'); to var LocalStrategy = require('passport-local').Strategy; fixes this issue. Incase anyone else is having the same problem.
I'm trying to build a user authentication system into my Node app with Passport.js. When I try to sign up as a new user, it seems to work fine. But when I try logging in, the command prompt gives me this:
throw er; // Unhandled 'error' event
^
TypeError: done is not a function
at C:\spectray\config\passport.js:55:22
at C:\spectray\node_modules\mongoose\lib\model.js:3419:16
at C:\spectray\node_modules\kareem\index.js:212:48
at C:\spectray\node_modules\kareem\index.js:127:16
at _combinedTickCallback (internal/process/next_tick.js:67:7)
at process._tickCallback (internal/process/next_tick.js:98:9)
Here's my passport.js file:
var passport = require('passport'), LocalStrategy = require('passport-local').Strategy;
var User = require('../app/models/user');
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({
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 taken.'));
} 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(new LocalStrategy({
passReqToCallback : true
},
function(username, password, done) {
User.findOne({ username: username }, function(err, user) {
if (err) { return done(err); }
if (!user) {
return done(null, false, { message: 'Incorrect username.' });
}
if (!user.validPassword(password)) {
return done(null, false, { message: 'Incorrect password.' });
}
return done(null, user);
});
}
));
And here's my server.js file:
var express = require('express');
var app = express();
var port = process.env.PORT || 8080;
var mongoose = require('mongoose');
var passport = require('passport');
var morgan = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var session = require('express-session');
var flash = require('connect-flash');
var db = require('./config/database.js');
var favicon = require('serve-favicon');
app.use(favicon(__dirname + '/public/imgs/favicon.ico'));
mongoose.Promise = global.Promise;
mongoose.connect(db.url);
require('./config/passport');
app.use(morgan('dev'));
app.use(cookieParser());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.set('view engine', 'ejs');
app.use(session({ secret: 'penniesfromheaven', resave: true, saveUninitialized: true }));
app.use(passport.initialize());
app.use(passport.session());
app.use(flash());
app.use(express.static(__dirname + '/public'));
require('./app/routes.js')(app, passport);
app.listen(port);
console.log('The magic happens on port ' + port);
I tried deleting my node_modules folder and running npm install, but this error still shows up. What am I doing wrong?
Because you are setting the passReqToCallback option to true in the LocalStrategy constructor, your callback function gets called with these arguments: (req, username, password, done), but your function is accepting (username, password, done), which is why the arguments are getting assigned to the wrong parameters (and thus why done isn't a function as the error message says). To fix this, try removing the passReqToCallback option, like this:
passport.use(new LocalStrategy(function(username, password, done) {
User.findOne({ username: username }, function(err, user) {
if (err) { return done(err); }
if (!user) {
return done(null, false, { message: 'Incorrect username.' });
}
if (!user.validPassword(password)) {
return done(null, false, { message: 'Incorrect password.' });
}
return done(null, user);
});
}));
Or, if you decide later that you need the req in your LocalStrategy, then add the parameter to the function, like this:
passport.use(new LocalStrategy({
passReqToCallback : true
},
function(req, username, password, done) {
User.findOne({ username: username }, function(err, user) {
if (err) { return done(err); }
if (!user) {
return done(null, false, { message: 'Incorrect username.' });
}
if (!user.validPassword(password)) {
return done(null, false, { message: 'Incorrect password.' });
}
return done(null, user);
});
}
));
I had this code working at some point and must have lost it in a careless save at some point. I am trying to achieve persistent login with passport but it does not seem to be doing that as I am getting false on the isAuthentiacted middleware.
Here is my primary server.js setup, as you can see the order is good. But I am not sure about the cookie settings as I'm new to this whole thing.
app.use(cookieParser('S3CRE7'));
app.use(bodyParser.json());
app.use(session({ key: 'express.sid', resave: false, saveUninitialized: false, maxAge: 3000}));
app.use(passport.initialize());
app.use(passport.session());
app.use('/users/', usersRouter);
app.use('/transcriptions', transRouter);
app.use(express.static('public'));
const basicStrategy = new BasicStrategy(function(username, password, callback) {
let user;
User
.findOne({username: username})
.exec()
.then(_user => {
user = _user;
if (!user) {
return callback(null, false, {message: 'Incorrect username'});
}
return user.validatePassword(password);
})
.then(isValid => {
if (!isValid) {
return callback(null, false, {message: 'Incorrect password'});
}
else {
return callback(null, user)
}
});
});
passport.use(basicStrategy);
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
User.findById(id, function(err, user) {
done(err, user);
});
});
Here is my initial Log In endpoint with custom callback function, which logs in just fine, as well as stores a cookie on the client side
router.post('/login', function(req, res, next) {
passport.authenticate('basic', function (err, account) {
req.logIn(account, function() {
res.status(err ? 500 : 200).send(err ? err : account);
});
})(req, res, next)
});
isAuthenticated function:
const isAuthenticated = function (req, res, next) {
if (req.isAuthenticated())
return next();
console.log('not authenticated');
}
First lines of where the authentication fails:
router.get('/', isAuthenticated,
(req, res) => {
console.log(req);
});
My passport middleware is not working. When I call passport.authenticate() on a route to confirm the user is authenticated, I am redirected to the failure page. The login route however works as expected, and I am redirected successfully to the correct page, where the failure middleware redirect is called and I am sent back to the login page.
I have a Passport strategy like so:
module.exports = function(){
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy
var User = require('../models/user');
// used to serialize the user for the session
passport.serializeUser(function(user, done) {
done(null, user.id);
});
// used to deserialize the user
passport.deserializeUser(function(id, done) {
User.getUserById(id, function(err, user) {
done(err, user);
});
});
passport.use(new LocalStrategy({
usernameField: "email",
passwordField: "password"
}, function(email, password, done){
User.getUserByEmail(email, function(err, user){
if(err) throw err;
if(!user){
console.log('unknown user');
return done(null, false, {message: 'Email not recognised, please try again'});
}
User.comparePassword(password, user.password, function(err, isMatch){
if(err) throw err;
if(isMatch){
return done(null, user);
} else {
console.log('Invalid password');
return done(null, false, { message: 'Password not recognised, please try again' });
}
});
});
}));
};
Logging in is fine using:
router.post('/user/login',
passport.authenticate('local', {
successRedirect: '/clients',
failureRedirect: '/user/login',
failureFlash: true
}
));
My '/clients' route is like so, where the authentication fails and redirects incorrectly back to the login page:
router.get('/clients',
passport.authenticate("local", {
failureRedirect: "/user/login",
failureFlash: "not verified"
}), function(req, res, next) {
res.locals.client = null;
Client.find({})
.select("name")
.select("_id")
.exec(function(err, clients){
res.render('client/views/clients', {
title: 'Clients',
clients: clients
});
});
});
Server passport initialization like so:
//passport
app.use(passport.initialize());
app.use(passport.session());
app.use(bodyParser.urlencoded({ extended: false }));
require("./user/services/passport")(passport);
What am I doing wrong?
As you have used failureRedirect: '/user/login' . It will redirect you to the login page. If you want to redirect it to someother page change the failureRedirect value to that corresponding route.
I am currently working on a node js project with passport authentication.
But i get the following error message:
Error: "Unknown authentication strategy "
Here is my Code:
LocalStrategy = require('passport-local').Strategy;
var UserModel = 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){
return done(err, user);
});
});
passport.use('local-signup', new LocalStrategy({
passReqToCallback: true
}, function(req, username, password, done){
process.nextTick(function(){
User.findOne({username: username}, function(err, user) {
if(err){
return done(err);
}
if(user){
return done(null, false, req.flash('signUpErr', 'The mail is taken'));
} else {
var newUser = new UserModel();
newUser.name = username;
newUser.password = newUser.generateHash(password);
newUser.save(function(err){
if(err){
throw err;
}
console.log('All Ok');
return done(null, newUser);
})
}
});
});
}));
}
Route:
//Post requests
app.post('/signup', passport.authenticate('local-signup', {
successRedirect: '/',
failureRedirect : '/signup'
}));
My model:
var mongoose = require('mongoose');
var bcrypt = require('bcrypt-nodejs');
var UserSchema = new mongoose.Schema({
name: String,
password: String
});
UserSchema.method.generateHash = function(password){
return bcrypt.hash(password);
};
module.exports = mongoose.model('UserModel', UserSchema);
I would really need your help, thanks!
Check if you passing the strategy along with the user credentials
var credentials = {
username:"username",
password:"password",
strategy:"local"
};
$http.post('auth/signin', credentials);
Server side
function passportAuthenticate(req, res, next, strategy) {
passport.authenticate(strategy, function(err, user, info) {
if (err || !user) {
res.status(400).send(info);
} else {
next(req, res, user);
}
})(req, res, next);
}