25

I am trying to integrate passport to my code's login form. Client side calling server side works as it should until i call passport.authenticate in the request, 400 Bad Request was returned. What am I missing here.

HTML

        <div>
            <div class="row">
                <div class="input-field col s12">
                    <input id="user-email" type="text" ng-model="user.email">
                    <label for="user-email">Your email address</label>
                </div>
            </div>
            <div class="row">
                <div class="input-field col s12">
                    <input id="user-password" type="password" ng-model="user.password">
                    <label for="user-password">Your password</label>
                </div>
            </div>
            <div id="login-button-panel" class="center-align">
                <button class="btn" id="login-btn" ng-click="vm.login(user);">Login</button> 
            </div>
            <div class="section center">
                <a class="modal-trigger">Forgot password?</a>
            </div>
        </div>

JS

$http.post('/api/login',user).success(function(result){
    console.log(result)
})

server.js

passport.use(new LocalStrategy(
    function(username, password, done) {
        return done(null, false, {message:'Unable to login'})
    }
));
passport.serializeUser(function(user,done){
    done(null,user);
});

passport.deserializeUser(function(user,done){
    done(null,user);
});
app.post('/api/login', passport.authenticate('local'), function(req,res){
    res.json(req.user)
});
Gene Lim
  • 1,068
  • 2
  • 14
  • 36

5 Answers5

57

Bad Request was thrown by passport for missing access on username and password.

It is checking body and URL query for fields username and password. If either is falsy the request is rejected with status 400.

On creating your LocalStrategy you may pass set of options in additional argument to constructor choosing differently named fields using options usernameField and/or passwordField. In your particular case this would look like this:

passport.use(new LocalStrategy(
    {usernameField:"user-email", passwordField:"user-password"},
    function(username, password, done) {
        return done(null, false, {message:'Unable to login'})
    }
));
Thomas Urban
  • 4,649
  • 26
  • 32
14

In my case (Express 4.0), I wasn't using body-parser

Jeff Hoye
  • 580
  • 5
  • 11
7

This error also comes from trying to access the request payload without using body-parser

Use -

var parser = require('body-parser');
var urlencodedParser = parser.urlencoded({extended : false});


    app.post("/authenticate", urlencodedParser, passport.authenticate('local'), function (request, response)
    {           
        response.redirect('/');                      
    });
Dan O
  • 6,022
  • 2
  • 32
  • 50
Vandana Sharma
  • 126
  • 1
  • 7
2
passport.use(new LocalStrategy(
    {
        usernameField: 'email',
        passwordField: 'password'
    },
    function (email, password, done) {
        db.collection('User').findOne({ email: email }, async function (err, user) {
            console.log('user requested password caught in passport', password);
            if (err) { return done(err); }
            if (!user) { return done(null, false); }
            const matchPassword = await comparePassword(password, user.password);
            if (!matchPassword) { return done(null, false); }
            return done(null, user);
        });
    }
));
  • 1
    Try to explain more clearly why this is an answer to the question. – Jeroen Heier Feb 06 '19 at 05:47
  • 1
    by default LocalStrategy takes takes username and password while authenticating from the request but we need is email and password.To make this happen we need { usernameField: 'email', passwordField: 'password' } – LekhRazz Rokaya Feb 06 '19 at 08:26
0
app.post("/register",function(req,res){
  Client.register({username:req.body.email},req.body.password,function(err,client){
    if(err){
      console.log(err);
      res.redirect("/register")
    }
    else{
      passport.authenticate("local")(req,res,function(){
        console.log("success");
        res.redirect("/secrets")
      })
    }
  })
})
  • 1
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Aug 31 '22 at 12:13