For some context: I'm trying to make a basic login system. At the moment, signing up works with no problems. Logging in also seems to be okay, it makes a connection with the database properly - however, the big problem is that the login itself is not saved/recognized. I see no cookie or anything else that would indicate that the server is recognizing the login. I'm working in NodeJS, and the backend is hosted on my VPS (running Ubuntu). Trying to get some advice from ChatGPT didn't really help out unfortunately.
I have two endpoints mainly used for logging in. One is called api/login and the other is api/auth-check. api/login returns a 200 OK, with the response of {"success":true}
. api/auth-check on the other hand returns a 304 not modified, and returns a {"loggedIn":false}
. I made sure to check in my frontend code that any fetch being done towards api/auth-check and api/login includes credentials: 'include'
.
The reason why I need a session/cookie and for the server to remember the login is because I want to make the login & signup buttons disappear when a user logs in, and instead display "logout" and some other text. It also has to do with some other logic that I'm doing on the site which requires the user to be logged in to perform certain functions/tasks.
Here's how my current backend looks like for my api/login:
app.post('/api/login', async (req, res) => {
try {
const { email, password } = req.body;
if (!email || !password) {
return res.status(400).json({ error: 'Missing email or password' });
}
const [rows] = await db.query(
'SELECT user_id, password FROM users WHERE email = ?',
[email]
);
if (!rows.length) {
return res.status(401).json({ error: 'Invalid email or password' });
}
const user = rows[0];
if (user.password !== password) {
return res.status(401).json({ error: 'Invalid email or password' });
}
req.session.userId = user.id;
return res.json({ success: true });
} catch (error) {
console.error('Login error:', error);
return res.status(500).json({ error: 'Server error' });
}
});
And here is my api/auth-check:
app.get('/api/auth-check', async (req, res) => {
if (!req.session.userId) {
return res.json({ loggedIn: false });
}
try {
const [rows] = await db.query(
'SELECT email FROM users WHERE user_id = ?',
[req.session.userId]
);
if (!rows.length) {
return res.json({ loggedIn: false });
}
return res.json({
loggedIn: true,
email: rows[0].email,
});
} catch (error) {
console.error('Auth check error:', error);
return res.status(500).json({ error: 'Server error' });
}
});
The most likely reason your session isn’t being saved or recognized is because you didn’t configure or use express-session
properly on your backend.
Even though you're assigning req.session.userId
, that won’t persist unless you have this middleware set up:
const session = require('express-session');
app.use(session({
secret: 'your-secret-key',
resave: false,
saveUninitialized: false,
cookie: {
secure: false, // set to true if using HTTPS
httpOnly: true,
sameSite: 'lax',
}
}));
And your frontend is sending cookies correctly, you're doing this right:
fetch('/api/login', {
method: 'POST',
credentials: 'include',
...
});
Also check if you’re not missing app.use(express.json())
or express.urlencoded()
before your routes.
Your user.id
exists (req.session.userId = user.id)
but your DB returns user_id
, so this might be undefined
! Replace with:
req.session.userId = user.user_id;