saintedlama / passport-local-mongoose

Passport-Local Mongoose is a Mongoose plugin that simplifies building username and password login with Passport
MIT License
1.17k stars 295 forks source link

/login 500 with React/axios #288

Closed coltonoscopy closed 5 years ago

coltonoscopy commented 5 years ago

Hello!

In using the following /login route, I'm getting a silent 500 without the console.log firing, which is leading me to believe there's some sort of issue with passport, perhaps a configuration or the like:

  router.post('/login', passport.authenticate('local'), (req, res) => {
  console.log('Accessing the login route');
  res.statusCode = 200;
  res.setHeader('Content-Type', 'application/json');
  res.json({
    message: 'Successful login!'
  });
});

I have the following /register route which seems to work perfectly:

router.post('/register', (req, res, next) => {
  User.register(new User({
      username: req.body.username
    }),
    req.body.password, (err, user) => {
    if (err) {
      res.statusCode = 500;
      res.setHeader('Content-Type', 'application/json');
      res.json({
        err: err
      });
    } else {
      passport.authenticate('local')(req, res, () => {
        User.findOne({
          username: req.body.username
        }, (err, person) => {
          res.statusCode = 200;
          res.setHeader('Content-Type', 'application/json');
          res.json({
            success: true,
            status: 'Registration Successful!'
          });
        });
      });
    }
  });
});

Both are being accessed in my React app through axios, where I'm simply passing along the username/password via the following function when logging in as an example:

submitForm() {
        axios.post('http://localhost:4000/users/register', {
            username : this.state.username,
            password : this.state.password
        })
        .then((res) => {
            console.log(res);
            console.log('Response received!');
        })
        .catch((err) => {
            console.log(err);
        });
    }

Finally, here's my app.js and User model files, in case something may be awry there:

var createError = require('http-errors');
var express = require('express');
var path = require('path');
var bodyParser = require('body-parser');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var cors = require('cors');
const passport = require('passport'),
  LocalStrategy = require('passport-local').Strategy;
var session = require('express-session');

var indexRouter = require('./routes/index');
var registerRouter = require('./routes/register');
var usersRouter = require('./routes/users');
var testRouter = require('./routes/test');

const User = require('./models/user');

var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/test', { useNewUrlParser: true });

var db = mongoose.connection;

db.on('error', console.error.bind(console, 'connection error:'));

var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');

app.use(cors());
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.static(path.join(__dirname, 'public')));

app.use(session({
  name: 'session-id',
  secret: 'blahblahblah',
  saveUninitialized: false,
  resave: false
}));

passport.use(new LocalStrategy(User.authenticate()));
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());

app.use('/', indexRouter);
app.use('/users', usersRouter);
app.use('/register', registerRouter);
app.use('/test', testRouter);

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  next(createError(404));
});

// error handler
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render('error');
});

app.listen(4000);

module.exports = app;
const mongoose = require('mongoose'),
    Schema = mongoose.Schema,
    passportLocalMongoose = require('passport-local-mongoose');

const User = new Schema({
    username: {
        type: String,
        unique: true,
        required: true
    }
});

User.plugin(passportLocalMongoose);

module.exports = mongoose.model('User', User);

If anything is glaringly wrong, help would be much appreciated (currently just fails silently accessing /login with a 500). I suspect it's not so much a React issue or accessing things through axios as it is a passport config problem, but it's been eluding me for some time now. Thanks so much!

coltonoscopy commented 5 years ago

I figured it out; for some reason I missed adding:

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