Working on a MERN app, using passport / passport-local / passport-local-mongoose for user authentication and sessions. User registration works perfectly- a new user is created, a session is created, and req.session.user is set to the new user. User login creates a new session, but it doesn't login in the user or add anything to req.session.user.
I know similar questions have been asked on here- I've been going through all those questions and answers for the last three days, and nothing that's already been done works for me. It's not a CORS problem (I've set 'Access-Control-Allow-Origin' to * on all requests), my done() function is set up correctly, etc.
Relevant code:
server.js
...
const localStrategy = new LocalStrategy(
{usernameField: 'email',
passwordField: 'password'},
function(username, password, done) {
User.authenticate()(username, password, function(err, user) {
if (err) return done(err)
if (!user) return done(null, false)
return done(null, user)
})
}
)
app.use(express.json())
app.use(express.urlencoded({extended: false}))
app.use(session({
secret: process.env.SESSION_SECRET,
resave: false,
saveUninitialized: true,
store: new MongoStore({mongoUrl: process.env.MONGO_URI}),
cookie: {
maxAge: 1000 * 60 * 60 * 24 * 7, // 1 week
expires: 1000 * 60 * 60 * 24 * 7, // 1 week
secure: process.env.NODE_ENV === 'production',
sameSite: 'none',
},
}))
passport.use('local', localStrategy)
passport.serializeUser(User.serializeUser())
passport.deserializeUser(User.deserializeUser())
app.use(passport.initialize())
app.use(passport.session())
app.post('/api/users/login', passport.authenticate('local'), (err, req, res, next) => {
if (err) {
res.status(203).send(err)
next(err)
} else {
res.status(200).send(req.user._id)}
})
app.use("/api/users", userRoutes)
...
Originally I had the login route in the userRoutes.js file, I moved it to the server in hopes that would fix things (it didn't). Here's the functional register route in userRoutes.js:
router.route('/register').post((req, res, next) => {
User.register(
new User({
email: req.body.email,
username: req.body.email
}), req.body.password, function (err, msg) {
if (err) {
res.send(err)
} else {
passport.authenticate('local', (err, user, info) => {
if(err) {
res.status(203).send(err)
} else {
if(user) {
req.login(user, err => {
req.session.user = user
console.log(req.session)
res.status(200).send(user._id)
})
} else {
res.status(202).send(info)
}
}
})(req, res, next)
I don't have a passport.js or anything like that- all my passport setup is being done directly in server.js .
The userModel.js file is just a simple user schema.
Attemping login always returns 401 (Unauthorized).
Existing solutions on existing StackOverflow questions
- Set CORS; already doing, works great with /register but not /login
- Check done() function to make sure Passport is being passed the user; done
- Make sure JWT is set up correctly - not applicable, I'm not using JWT
- Make sure password is being decrpyted correctly; I'm not decrypting it, I'm letting passport-local-mongoose handle that (through userSchema.plugin(passportLocalMongoose).
- Make sure passport-local is being passed 'email' in the username field- done (see my localStrategy)
AFAIK, I've tried every existing solution on here with no luck.