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);
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);
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 }) );