We have an Express application with authentication routes (postLogin and getLogin) and session configuration set up using express-session. Despite configuring sessions, I encounter an issue where session data is not persisting between requests.
PostLogin: I am creating the session for the user here.
const postLogin = async (req, res) => {
const { username, password } = req.body;
try {
// Query database for user
const user = await getUserByUsername(username);
// Validate password
const passwordMatch = await bcrypt.compare(password, user.password);
if (!passwordMatch) {
res.status(401).json({ error: 'Invalid username or password' });
return;
}
// Set session data
req.session.user = {
id: user.id,
username: user.username
};
req.session.save();
res.json({
loggedIn: true,
username: user.username
});
} catch (error) {
console.error('Login error:', error);
res.status(500).json({ error: 'Internal server error' });
}
};
GetLogin: Checking for user session data on page refresh in my front end to see if user session is available. This always returns null for some reason.
const getLogin = (req, res) => {
if (req.session.user && req.session.user.username) {
res.json({
loggedIn: true,
username: req.session.user.username
});
} else {
res.json({ loggedIn: false });
}
};
Express Session Config: (Update): edited cors to allow origin requests.
const express = require('express');
const session = require('express-session');
const cors = require('cors');
const app = express();
app.use(cors({
origin: ['http://localhost:5173'], // cannot be '*'
credentials: true,
}));
app.use(session({
secret: process.env.COOKIE_SECRET,
resave: false,
saveUninitialized: false,
cookie: {
secure: process.env.ENVIRONMENT === 'production',
sameSite: process.env.ENVIRONMENT === 'production' ? 'none' : 'lax'
}
}));
Front-end axios request (React JSX)
import { createContext, useState, useEffect } from "react";
import { useNavigate } from "react-router-dom";
export const AccountContext = createContext();
const UserContext = ({ children }) => {
const [user, setUser] = useState({ loggedIn: null });
const navigate = useNavigate();
useEffect(() => {
console.log("Using effect");
fetch("http://localhost:8080/api/v1/auth/login", {
method: "GET",
credentials: "include", // Include credentials in the request
})
.then((response) => {
if (!response || !response.ok) {
setUser({ loggedIn: false });
return null;
}
return response.json();
})
.then((data) => {
if (data) {
setUser(data);
navigate("/home");
}
})
.catch((error) => {
console.error("Error fetching user data:", error);
setUser({ loggedIn: false });
});
}, []);
return (
<AccountContext.Provider value={{ user, setUser }}>
{children}
</AccountContext.Provider>
);
};
export default UserContext;