Vicky R Vicky R - 2 months ago 48
Node.js Question

Passportjs local strategy missing credentials error message

I am trying to implement authentication in node.js application using passportjs with passport-local strategy. I read documentation carefully and used all thing which were suggested into documentation. But I'm getting always "missing credential" message every time.

Node.js File:

var http = require('http');
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 app = express();
app.set('port', process.env.PORT || 3000);

// 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(express.static(path.join(__dirname, 'public')));
app.use(cookieParser());
app.use(require('body-parser').urlencoded({
extended: true
}));
app.use(require('express-session')({
secret: 'P@ssP0rtJs',
resave: true,
saveUninitialized: true
}));
app.use(require('flash')());
app.use(passport.initialize());
app.use(passport.session());

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

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

passport.use(new localStrategy(function (username, password, done) {
var displayName = 'Test User',
loginUsername = 'testuser',
loginPassword = 'test',
user = {
"id": '1001',
"display": displayName,
"username": loginUsername,
"password": loginPassword,
"loggedin": '1'
};
if (loginUsername != username && loginPassword != password) {
return done(null, false, {
type: "error",
message: 'Either username or password is wrong.'
});
}
return done(null, user);
}));

// routes

/* GET Home page. */
app.get('/', passport.authenticate('local', {
failureRedirect: '/login',
failureFlash: true
}), function (req, res, next) {
res.render('index', {
title: 'Express'
});
});

/* GET user login. */
app.get('/login', function (req, res, next) {
res.render('login', {
title: 'Login'
});
});

/* POST user login. */
app.post('/login', passport.authenticate('local', {
failureRedirect: '/login',
failureFlash: true
}), function (req, res, next) {
res.redirect('/');
});

/* GET logout page. */
app.get('/logout', function (req, res, next) {
req.logout();
res.redirect('/login');
});

// 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: {}
});
});

var server = http.createServer(app).once('error', function (err) {
if (err.code === 'EADDRINUSE') {
console.log('port is currently in use');
}
}).listen(app.get('port'), function () {
// console will print the message
console.log('Express server listening on port ' + app.get('port'));
});


I did a lots search but couldn't find a solution from other post. When I saw console and find this output.

Express server listening on port 3000
GET /login 200 381.482 ms - 465
GET /stylesheets/style.css 304 1.685 ms - -
POST /login 302 24.303 ms - 58
GET / 302 2.419 ms - 68
GET /login 200 32.336 ms - 528
GET /stylesheets/style.css 304 0.563 ms - -


package.json

{
"name": "passport-demo",
"version": "0.0.0",
"private": true,
"scripts": {
"start": "node ./app.js $PORT"
},
"dependencies": {
"body-parser": "~1.13.2",
"cookie-parser": "~1.3.5",
"debug": "~2.2.0",
"express": "~4.13.1",
"jade": "~1.11.0",
"morgan": "~1.6.1",
"serve-favicon": "~2.3.0",
"express-session": "~1.13.0",
"passport": "~0.3.2",
"passport-local": "~1.0.0",
"flash": "~1.1.0"
}
}


Does anyone know what I'm missing here?

Thanks!

Answer

passport.authenticate('local') middleware is used when you are trying to verify user credentials from POST body. So it should be used only for POST /login route. But you are also using this middleware in GET /, and thus the error, since this route doesn't have any POST body.

To check if a user is logged in, use req.isAuthenticated() method:

const isAuthenticated = function (req, res, next) {
  if(req.isAuthenticated()) return next();
  else res.redirect('/login')

}
app.get('/', isAuthenticated, function (req, res, next) {
    res.render('index', {
        title: 'Express'
    });
});