Reputation: 103
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);
Upvotes: 6
Views: 20253
Reputation: 4967
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
.
Upvotes: 0
Reputation: 1806
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. E.g
passport.use( new passportLocal({
usernameField: 'email',
passwordField: 'passwd'
}, func..));
Upvotes: 2
Reputation: 1508
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.
Upvotes: 23
Reputation: 692
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);
Upvotes: 17