Saturday, 8 April 2017

Why can't I POST /login with Node and Passport?

I am setting up Passport with Node/Express app (with MongoDB). For some reason I am unable to POST to /login. Strangely, the BasicStrategy instance I've set up isn't even running at all.

When I run it in Postman, I get the html file back. When I try it in the browser, for some reason I get a 200 response with the failureRedirect.

The strangest thing is that the strategy is not being called at all; the terminal console doesn't log any of the console.logs that I have set up whatsoever.

Any help would be highly appreciated. Thank you.

Here is my login router:

/users/routes/loginRouter.js

const {BasicStrategy} = require('passport-http'),
      express = require('express'),
      jsonParser = require('body-parser').json(),
      passport = require('passport');

const {User} = require('../models');

const loginRouter = express.Router();

loginRouter.use(jsonParser);

const strategy = new BasicStrategy(function(username, password, callback) {
  console.log(arguments);
  let user;
  User
    .findOne({username: username})
    .exec()
    .then(_user => {
      console.log(_user);
      user = _user;
      if (!user) {
        return callback(null, false, {message: 'Incorrect username'});
      }
      return user.validatePassword(password);
    })
    .then(isValid => {
      console.log(isValid);
      if (!isValid) {
        return callback(null, false, {messsage: 'Incorrect password'});
      }
      else {
        return callback(null, user)
      }
    });
});

passport.use(strategy);
loginRouter.use(passport.initialize());

loginRouter.post('/',
  passport.authenticate('basic',
    {
      session: true,
      successRedirect: '/console',
      failureRedirect: '/login'
    }
  )
);

module.exports = {loginRouter};

Now this is my server file:

/server.js

const express = require('express'),
      bodyParser = require('body-parser'),
      mongoose = require('mongoose'),
      passport = require('passport');

const {adminRouter} = require('./users/routes/adminRouter'),
      {loginRouter} = require('./users/routes/loginRouter'),
      {registerRouter} = require('./users/routes/registerRouter'),
      {PORT, DATABASE_URL} = require('./config'),
      {router} = require('./router');


const app = express();
const path = require('path');

mongoose.Promise = global.Promise;

app.use(bodyParser.json());

app.use(express.static('public'));

app.use(passport.initialize());
app.use(passport.session());

app.use('/api/users/', registerRouter);
app.use('/login', loginRouter);
app.use('/console', adminRouter);

app.use('/', router);

app.get(['/login', '/register', '/about', '/archive', '/maxim/:maximId', '/console'], (req, res) => {
  res.sendFile(path.resolve(__dirname, 'public', 'index.html'))});


function runServer(databaseUrl=DATABASE_URL, port=PORT) {

  return new Promise((resolve, reject) => {
    mongoose.connect(databaseUrl, err => {
      if (err) {
        return reject(err);
      }
      server = app.listen(port, () => {
        console.log(`Your app is listening on port ${port}`);
        resolve();
      })
      .on('error', err => {
        mongoose.disconnect();
        reject(err);
      });
    });
  });
}

function closeServer() {
  return mongoose.disconnect().then(() => {
     return new Promise((resolve, reject) => {
       console.log('Closing server');
       server.close(err => {
         if (err) {
           return reject(err);
         }
         resolve();
       });
     });
  });
}

if (require.main === module) {
  runServer().catch(err => console.error(err));
};

module.exports = {app, runServer, closeServer};

My other routes are working perfectly fine, for example this register route is functioning as expected:

/users/routes/registerRouter.js

const {BasicStrategy} = require('passport-http'),
      express = require('express'),
      jsonParser = require('body-parser').json(),
      passport = require('passport');

const {User} = require('../models');

const registerRouter = express.Router();

registerRouter.use(jsonParser);

const strategy = new BasicStrategy(
  (username, password, cb) => {
    User
      .findOne({username})
      .exec()
      .then(user => {
        if (!user) {
          return cb(null, false, {
            message: 'No such user'
          });
        }
        if (user.password !== password) {
          return cb(null, false, 'Incorrect password');
        }
        return cb(null, user);
      })
      .catch(err => cb(err))
});

passport.use(strategy);

registerRouter.post('/', (req, res) => {
  if (!req.body) {
    return res.status(400).json({message: 'No request body'});
  }

  if (!('username' in req.body)) {
    return res.status(422).json({message: 'No username in request body'});
  }

  let {username, password, email} = req.body;

  if (typeof username !== 'string') {
    return res.status(422).json({message: 'Incorrect field type: username'});
  }

  username = username.trim();

  if (username === '') {
    return res.status(422).json({message: 'Incorrect field length: username'});
  }

  if (!(password)) {
    return res.status(422).json({message: 'No password in request body'});
  }

  if (typeof password !== 'string') {
    return res.status(422).json({message: 'Incorrect field type: password'});
  }

  password = password.trim();

  if (password === '') {
    return res.status(422).json({message: 'Incorrect field length: password'});
  }

  if (typeof email !== 'string') {
    return res.status(422).json({message: 'Incorrect field type: email'});
  }

  email = email.trim();

  if (email === '') {
    return res.status(422).json({message: 'Incorrect field length: email'});
  }

  // check for existing user
  return User
    .find({username})
    .count()
    .exec()
    .then(count => {
      if (count > 0) {
        return res.status(422).json({message: 'Username taken'});
      }
      // if no existing user, hash password
      return User.hashPassword(password)
    })
    .then(hash => {
      return User
        .create({
          username: username,
          password: hash,
          email: email
        })
    })
    .then(user => {
      return res.status(201).json(user.apiRep());
    })
    .catch(err => {
      res.status(500).json({message: 'Internal Server Error'})
    });
});

module.exports = {registerRouter};



via Alacritas

No comments:

Post a Comment