jaredhanson / passport

Simple, unobtrusive authentication for Node.js.
https://www.passportjs.org?utm_source=github&utm_medium=referral&utm_campaign=passport&utm_content=about
MIT License
22.93k stars 1.24k forks source link

Only one STRATEGY working from mutiple STRATEGIES #587

Closed MKRNaqeebi closed 2 years ago

MKRNaqeebi commented 7 years ago

I have 2+ models and want to make login differently for each but only first STRATEGY working other not and not even showing errors just login successfully and then on req.isAuthenticated() return false. Here is my code of index.js file

var express = require('express');
var router = express.Router();
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;

var User = require('../models/user');

// Register
router.get('/users/register', function(req, res){
    res.render('register', {title: "Register"});
});

// Login
router.get('/users/login', function(req, res){
    res.render('login', {title: "Login"});
});

// Register User
router.post('/users/register', function(req, res){
    var firstName = req.body.firstName;
    var lastName = req.body.lastName;
    var email = req.body.email;
    var username = req.body.username;
    var password = req.body.password;
    var password2 = req.body.password2;

    // Validation
    req.checkBody('firstName', 'Name is required').notEmpty();
    req.checkBody('lastName', '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({
            firstName: firstName,
            lastName: lastName,
            email:email,
            username: username,
            password: password
        });

        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/login');
    }
});

passport.use('users', 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'});
            }
        });
    });
}));

router.post('/users/login',
    passport.authenticate('users', {successRedirect:'/', failureRedirect:'/users/login',failureFlash: true}),
    function(req, res) {
        res.redirect('/');
    });

router.get('/users/logout', function(req, res){
    req.logout();
    req.flash('success_msg', 'You are logged out');
    res.redirect('/users/login');
});

var Cook = require('../models/cook');

// Register
router.get('/register', function(req, res){

    var menu = {
        'Login':'/cook/login',
        'Register':'/cook/register'
    };
    res.render('register', {title: "Register", menu: menu});
});

// Login
router.get('/cook/login', function(req, res){

    var menu = {
        'Login':'/cook/login',
        'Register':'/cook/register'
    };
    res.render('login', {title: "Login", menu: menu});
});

// Register Cook
router.post('/cook/register', function(req, res){
    var firstName = req.body.firstName;
    var lastName = req.body.lastName;
    var email = req.body.email;
    var username = req.body.username;
    var password = req.body.password;
    var password2 = req.body.password2;

    // Validation
    req.checkBody('firstName', 'Name is required').notEmpty();
    req.checkBody('lastName', '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 newCook = new Cook({
            firstName: firstName,
            lastName: lastName,
            email:email,
            username: username,
            password: password
        });

        Cook.createCook(newCook, function(err, cook){
            if(err) throw err;
            console.log(cook);
        });

        req.flash('success_msg', 'You are registered and can now login');

        res.redirect('/cook/login');
    }
});

passport.use('cook', new LocalStrategy(function(username, password, done) {
    Cook.getCookByUsername(username, function(err, cook){
        if(err) throw err;
        if(!cook){
            return done(null, false, {message: 'Unknown Cook'});
        }
        Cook.comparePassword(password, cook.password, function(err, isMatch){
            if(err) throw err;
            if(isMatch){
                return done(null, cook);
            } else {
                return done(null, false, {message: 'Invalid password'});
            }
        });
    });
}));

router.post('/cook/login',
    passport.authenticate('cook', {successRedirect:'/', failureRedirect:'/cook/login',failureFlash: true}),
    function(req, res) {
        res.redirect('/');
    }
);

router.get('/cook/logout', function(req, res){
    req.logout();
    req.flash('success_msg', 'You are logged out');
    res.redirect('/cook/login');
});

passport.serializeUser(function(user, done) {
    done(null, user.id);
});

passport.deserializeUser(function(id, done) {
    Cook.getCookById(id, function(err, user) {
        done(err, user);
    });
});

// Get Homepage
router.get('/', ensureAuthenticated, function(req, res){
    res.send("Hello World");//render('index',{ title : "Dashboard" });
});

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; 

and main file app.js which is fine I think


var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var exphbs = require('express-handlebars');
var expressValidator = require('express-validator');
var flash = require('connect-flash');
var session = require('express-session');
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var mongo = require('mongodb');
var mongoose = require('mongoose');

mongoose.connect('mongodb://localhost/loginapp');
var db = mongoose.connection;

var routes = require('./routes/index');

// Init App
var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');

// BodyParser Middleware
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());

// Set Static Folder
app.use(express.static(path.join(__dirname, 'public')));

// Express Session
app.use(session({
    secret: 'secret',
    saveUninitialized: true,
    resave: true
}));

// Passport init
app.use(passport.initialize());
app.use(passport.session());

// Express Validator
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
        };
    }
}));

// Connect Flash
app.use(flash());

// Global Vars
app.use(function (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');
    res.locals.user = req.user || null;
    next();
});

app.use('/', routes);

// Set Port
app.set('port', (process.env.PORT || 3000));

app.listen(app.get('port'), function(){
    console.log('Server started on port '+app.get('port'));
}); 

I am working on that issue like 2+ days not able to solve and I write multiple STRATEGIES after reading issue#50

insankim commented 7 years ago

Have you tried this? https://stackoverflow.com/questions/20322384/how-to-serialize-deserialize-multiple-local-strategie I'm still a newbie to nodejs but this approach has appeared to work. I needed to add snippet of deserialize code for an additional strategy.