title: 400 ( bad request ) using fetch to login
body: <p>I am attempting to use fetch to POST a login form my to login function using passport. </p>
  
  <p>The login works when using the standard form action="/login", but I wanted to go over to fetch to be able to show realtime error output if login fails without refresh... </p>
  
  <p>I am getting 400 ( bad request ) and Uncaught (in promise) SyntaxError: Unexpected token B in JSON at position 0 when sending a login request... </p>
  
  <p>here's my code: </p>
  
  <pre><code>let payload = {
    username: "user1@user1.se",
    password: "superman123"
  };
  
  let data = new FormData();
  data.append( "json", JSON.stringify( payload ) );
  
  console.log(data);
  fetch('/login', {
    method: 'post',
    body: data
  }).then(function(response) {
    // if (response.status &gt;= 400) {
    //     throw new Error("Bad response from server");
    // }
    return response.json();
  })
  .then(function(data) {
    console.log(data);
  });
  </code></pre>
  
  <p>And here's my passport code: </p>
  
  <pre><code>var passport = require('passport');
  var Strategy = require('passport-local').Strategy;
  var db = require('./db');
  
  
  // Configure the local strategy for use by Passport.
  //
  // The local strategy require a `verify` function which receives the credentials
  // (`username` and `password`) submitted by the user.  The function must verify
  // that the password is correct and then invoke `cb` with a user object, which
  // will be set at `req.user` in route handlers after authentication.
  passport.use(new Strategy(
    function(username, password, cb) {
        console.log("1");
      db.users.findByUsername(username, function(err, user) {
        if (err) { return cb(err); }
        if (!user) { return cb(null, false); }
        if (user.password != password) { return cb(null, false); }
        return cb(null, user);
      });
    }));
  
  
  // Configure Passport authenticated session persistence.
  //
  // In order to restore authentication state across HTTP requests, Passport needs
  // to serialize users into and deserialize users out of the session.  The
  // typical implementation of this is as simple as supplying the user ID when
  // serializing, and querying the user record by ID from the database when
  // deserializing.
  passport.serializeUser(function(user, cb) {
    cb(null, user.id);
  });
  
  passport.deserializeUser(function(id, cb) {
    db.users.findById(id, function (err, user) {
      if (err) { return cb(err); }
      cb(null, user);
    });
  });
  app.use(passport.initialize());
  app.use(passport.session());
  
  app.get('/',
    require('connect-ensure-login').ensureLoggedIn("/login"),
    function(req, res){
      res.sendFile(path.join(__dirname+'/app/index.html'));
    });
  
  app.get('/login',
    function(req, res){
      res.sendFile(path.join(__dirname+'/app/public.html'));
    });
  
  
      app.post('/login', 
        passport.authenticate('local'),
        function(req, res) {
            console.log("post")
          res.redirect('/');
        });
  
      app.get('/logout',
        function(req, res){
          req.logout();
          res.redirect('/');
        });
  </code></pre>
  
  <p><strong>EDIT 1</strong>
  I was getting Uncaught <code>(in promise) SyntaxError: Unexpected token B in JSON at position 0</code> due to trying to parse an undefined response in .then(). But i still get the 400 error message.. Am I sending the data wrong?</p>
  
  <p><strong>EDIT 2</strong></p>
  
  <p>I modified my code to this, and now I am getting response.ok = true, however I get that even if I send the wrong login details... Do I need to update my strategy?</p>
  
  <pre><code>passport.use(new Strategy(
    function(username, password, cb) {
      db.users.findByUsername(username, function(err, user) {
        if (err) { return cb(err); }
        if (!user) { return cb(null, false); }
        if (user.password != password) { return cb(null, false); }
        return cb(null, user);
      });
    }));
  
  
  
  app.post('/login', function(req, res, next) {
    passport.authenticate('local', function(err, user, info) {
      switch (req.accepts('html', 'json')) {
        case 'html':
          if (err) { return next(err); }
          if (!user) { return res.redirect('/login'); }
          req.logIn(user, function(err) {
            if (err) { return next(err); }
            return res.redirect('/');
          });
          break;
        case 'json':
          if (err)  { return next(err); }
          if (!user) { return res.status(401).send({"ok": false}); }
          req.logIn(user, function(err) {
            if (err) { return res.status(401).send({"ok": false}); }
            return res.send({"ok": true});
          });
          break;
        default:
          res.status(406).send();
      }
    })(req, res, next);    
  });
  </code></pre>