Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

passport local strategy not getting called

I'm sure I'm missing something really obvious here, but I can't figure this out. The function I've passed to the LocalStrategy constructor doesn't get called when the login form gets submitted.

Code:

var express = require('express'); var http = require('http'); var path = require('path'); var swig = require('swig'); var passport = require('passport');  var LocalStrategy = require('passport-local').Strategy;  passport.serializeUser(function(user, done) {   console.log('Serialize user called.');   done(null, user.name); });  passport.deserializeUser(function(id, done) {   console.log('Deserialize user called.');   return done(null, {name: 'Oliver'}); });  passport.use(new LocalStrategy(   function(username, password, done) {     console.log('local strategy called with: %s', username);     return done(null, {name: username});   }));  var app = express();  app.set('port', process.env.PORT || 3000); app.set('view engine', 'swig'); app.set('views', __dirname + '/views'); app.use(express.favicon()); app.use(express.logger('dev')); app.use(express.bodyParser()); app.use(express.methodOverride()); app.use(express.cookieParser('asljASDR2084^^!')); app.use(express.session()); app.use(passport.initialize()); app.use(passport.session()); app.use(app.router); app.use(require('less-middleware')({ src: __dirname + '/public' })); app.use(express.static(path.join(__dirname, 'public'))); app.use(express.errorHandler({ dumpExceptions:true, showStack:true }));  app.engine('swig', swig.renderFile);  app.post('/auth', passport.authenticate('local')); app.get('/login', function(req, res) {   // login is a simple form that posts username and password /auth   res.render('login', {}); });  http.createServer(app).listen(app.get('port'), function(){   console.log('Express server listening on port ' + app.get('port')); }); 

The form on my /login page is cut and pasted from the passport docs except that I changed it to submit to /auth instead of /login:

<form action="/auth" method="post">     <div>         <label>Username:</label>         <input type="text" name="username"/>     </div>     <div>         <label>Password:</label>         <input type="password" name="password"/>     </div>     <div>         <input type="submit" value="Log In"/>     </div> </form> 

When I sumit the login form, the following gets logged

GET /login 200 5ms - 432b POST /auth 401 6ms 

Note that "local strategy called" is never logged.

Why isn't the function I passed to LocalStrategy getting called?

like image 961
Oliver Dain Avatar asked Sep 09 '13 01:09

Oliver Dain


People also ask

What is local strategy in passport?

passport-local is the strategy you would use if you are authenticating against a username and password stored 'locally' i.e. in the database of your app - 'local' means local to your application server, not local to the end user.

Can passport use multiple strategies?

Passport's middleware is built in a way that allows you to use multiple strategies in one passport.

How do passport sessions work?

Session based authentication is at the root of the passport-local strategy. This method of authentication is “server-side”, which means our Express application and database work together to keep the current authentication status of each user that visits our application.


2 Answers

I recently came across this problem and it can be caused by a number of things. First thing to check is ensuring that the bodyParser is set up for express, which I see that you have done.

app.use(express.bodyParser()); 

The next thing is ensuring that the form you are submitting to the route contains both a username AND password, and the user must also enter something in both fields. I was stumped for a bit testing it and not actually putting anything in the password field while testing :) Passport requires BOTH to execute the LocalStrategy verification function passed to passport.authenticate('local').

Your example also seems to be set up to capture both username and password properly, but in any case, you should try testing that the body is being parsed properly even without passport:

app.post('/auth', function(req, res){   console.log("body parsing", req.body);   //should be something like: {username: YOURUSERNAME, password: YOURPASSWORD} }); 

Else

Did you try adding a request handler to your /auth route?

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

or

app.post('/auth', passport.authenticate('local', { successRedirect: '/', failureRedirect: '/auth' })); 
like image 190
Arjun Mehta Avatar answered Oct 03 '22 14:10

Arjun Mehta


I encountered the same problem when I set up my own route handler from which I called passport.authenticate (). I forgot that passport.authenticate returns middleware that must be invoked, so just calling passport.authenticate isn't sufficient. Then I replaced

router.post("/",  function(req,res,next){    passport.authenticate("local", function(err, user, info){      // handle succes or failure    });  }) 

with

router.post("/",  function(req,res,next){    passport.authenticate("local", function(err, user, info){      // handle succes or failure    })(req,res,next);  }) 
like image 20
Jakub Kutrzeba Avatar answered Oct 03 '22 13:10

Jakub Kutrzeba