简体   繁体   中英

passport authentication failed in basic example

I am trying to break down this passport.js example to its most basic elements. I keep getting a 401 (Unauthorized) message and can't figure out why. Any help would be greatly appreciated.

Thank you!

Node.js file:

var http = require('http'),
express = require('express'),
passport = require('passport'),
LocalStrategy = require('passport-local').Strategy,
flash = require('connect-flash');

var port = process.env.PORT || 8080;

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

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

passport.use(new LocalStrategy(
  function(username, password, done) {
   console.log("LocalStrategy working...");
   return done(null, { id: 1, username: 'Joe', password: 'schmo'});
  }
));

var app = express();

app.configure(function(){
  app.use(express.static(__dirname + '/app'));
  app.use(express.cookieParser('big secret'));
  app.use(express.bodyParser());
  app.use(express.methodOverride());
  app.use(express.cookieSession());
  app.use(flash());
  app.use(passport.initialize());
  app.use(passport.session());
  app.use(app.router);
});

app.get('/', function (req, res) {
  res.sendfile(__dirname + '/index.html');
});

app.post('/login', passport.authenticate('local'), function (req, res) {
  console.log("authenticated....");
  res.end();
});

app.listen(port);

All users of new express.js (4.x and higher) together with passport.js could experience 'Missing credentials' trouble just because POST data is not parsed by default. To fix it install body-parser npm install body-parser and use in your code:

var bodyParser = require( 'body-parser' );
app.use( bodyParser.urlencoded({ extended: true }) );

Good point from @ivarni: app.use( bodyParser.urlencoded({ extended: true }) ); must be placed before injecting any passport middleware.

What does your index.html or login page look like? On your post you need to make sure you are sending at least something in the body with a username and a password field. If you send a post without those, you'll get a Missing credentials error message. If you want to change those, you can modify the parameters as shown on this guide .

You can inspect this yourself by adding a route to capture a login error, and specify that route on your call to passport.authenticate .

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

app.get('/loginerror') function(req,res) {
    console.log(req.flash('error'));
    res.redirect('/login');
}

I've modified your example to add the necessary forms. In addition, if there is any error, then it gets rendered on the login page. For example, if you just input a username and not a password, you'll see the "Missing credentials" error message. Hope this helps!

var http = require('http'),
    express = require('express'),
    passport = require('passport'),
    LocalStrategy = require('passport-local').Strategy,
    flash = require('connect-flash');

var port = process.env.PORT || 8080;

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

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

passport.use(new LocalStrategy(
    function(username, password, done) {
        console.log("LocalStrategy working...");
        return done(null, { id: 1, username: 'Joe', password: 'schmo'});
    }
));

var app = express();

app.configure(function(){
    app.use(express.static(__dirname + '/app'));
    app.use(express.cookieParser('big secret'));
    app.use(express.bodyParser());
    app.use(express.methodOverride());
    app.use(express.cookieSession());
    app.use(flash());
    app.use(passport.initialize());
    app.use(passport.session());
    app.use(app.router);
});

app.get('/', function(req, res){

    var username = "not logged in";

    if (req.user) {
        username = req.user.username;
    }

    var body = '<html><body>';
    body = body + '<p>' + username + '</p>';
    body = body + '<a href="/login">login</a>'
    body = body + '</body></html>'

    res.send(body);
});

app.get('/login', function(req, res){

    var message = req.flash('error');
    var body = '<div><p>' + message + '</p></div>';
    body = body + '<form action="/login" method="post">';
    body = body + '<div><label>Username:</label>';
    body = body + '<input type="text" name="username"/><br/></div>';
    body = body + '<div><label>Password:</label>';
    body = body + '<input type="password" name="password"/></div>';
    body = body + '<div><input type="submit" value="Submit"/></div></form>';
    res.send(body);
});

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

app.listen(port);

To anyone still receiving this error, double check the fields you send are indeed username & password . If not, you need to pass in extra parameters as suggested in the documentation . Eg

passport.use( new passportLocal({
  usernameField: 'email',
  passwordField: 'passwd'
}, func..));

I don't think the existing answers explicitly explain the problem which is: Passport Local Strategy will complain about missing credentials if req.body.username and req.body.password are missing.

Often the mistake is that the POST data has not been parsed, and that can be fixed by using body-parser .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM