Locally this
module.exports.isAuth = (req, res, next) => {
if (req.isAuthenticated()) {
next();
// res.status(200).json({ user: req.user, auth: true });
} else {
return res.status(401).json({ auth: false, msg: "Here" });
}
};
Works perfectly, I get logged in.
But when I try to do it with the backend on Heroku and not locally, I get the "Else" returned to the front end.
The problem is I know where the issue is, most likely, I just feel like I'm in an empty room looking for it.
I get the Json object returned on the front end, even though my passport middleware logs "logged in" on the server. heres the passport middleware
const passport = require("passport");
const LocalStrategy = require("passport-local").Strategy;
const connection = require("./database");
const mongoose = require("mongoose");
const User = mongoose.models.User;
const validPassword = require("../lib/passwordUtils").validPassword;
const cors = require("cors");
passport.use(
cors({
origin: [
"http://2607:fb90:b6e0:a363:f89f:be4b:a976:9ed0:3001",
"https://frontendfullstack.netlify.app",
"http://localhost:3001",
"localhost:3001",
],
credentials: true,
methods: "GET,HEAD,PUT,PATCH,POST,DELETE",
})
);
const customFields = {
usernameField: "username",
passwordField: "password",
};
passport.use(
new LocalStrategy(customFields, (username, password, done) => {
User.findOne({ username: username })
.then((user) => {
if (!user) {
console.log("No user");
return done(null, false);
} else {
const isValid = validPassword(password, user.hash, user.salt);
if (isValid) {
console.log("Logged in");
return done(null, user);
} else {
console.log("Wrong Password");
return done(null, true);
}
}
})
.catch((err) => {
done(err);
});
})
);
passport.serializeUser((user, done) => {
done(null, user.id);
});
passport.deserializeUser((id, done) => {
User.findById(id, (err, user) => {
done(err, user);
}).catch((err) => done(err));
});
And just to reiterate, when the server is local, it works, I get logged in and redirected, the site works perfectly.
The problem is that the Passport Local Strategy uses cookies for authentication, and Heroku only allows cookies to be set for its own domain.
As your frontend is hosted in Netlify, if you check the developer tools you will notice no cookie being set. So, the next request you make after logging in, fails.
Not much you can do except hosting the backend together with the frontend in Heroku, that way your app will work.
I answered a similar question a few days ago and left some tips at the end:
Not able to set/receive cookies cross-domain using Netlify and Heroku
Ok, let's see if we can make this work. I haven't worked with React, but the process for building the production app is somewhat similar to Angular from what I read.
First of all, you will want to revert to a prior commit where your app was working. Then create a new branch (i.e. backup) just to be sure if anything goes wrong, you can revert to it. Now, checkout to your main again. This is because Heroku will ignore commits pushed from branches that are not the main one.
Execute npm run build on your React app project folder and you will obtain the compiled files in a build folder. In there you will find the index.html file, and inside the build/static folder you'll find all the .js and .css files with hashed names that contain your app code.
Depending on what location this build folder was generated, you may need to manually copy it so it ends up as a folder inside your Express project folder tree.
Make sure the new folder isn't ignored (check the .gitignore file) so that it will be included in the next commit you'll make.
In the file that sets up your Express server (app.js, server.js or whatever you named it), in the part where the routes are setted, you need to add this line:
app.use(express.static(path.join(__dirname, 'build')));
This line will ensure that when you try to access the / path, Express will send the index.html file to the client. So, it will be just like is hosted in Netlify for example.
Now, you can git add . -> git commit -m 'Deploy test message' -> git push heroku main.
If everything went well, you can now visit the URL that Heroku assigned to your app and you'll see your frontend served in there.
Depending on your folders or environment variables you may run into some other problems, but this should work.
Let me know.