I’m encountering an issue with my React frontend application when trying to implement the logout functionality. When I attempt to logout from the frontend using a logout component, I consistently receive a 401 error. However, when I perform the logout operation directly from Postman, it works perfectly fine without any errors.
Here’s a bit more detail about my setup:
Backend: Node.js with Express serving as the API endpoint for user authentication and logout.
Frontend: React application using Axios for making HTTP requests.
Here’s how I’m implementing the logout functionality in my React application
Logout Component REACT
import React, { useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import { setLoading, clearUser } from "../../redux/userSlice";
import axios from "axios";
import { useNavigate } from "react-router-dom";
import { CiLogout } from "react-icons/ci";
const Logout = () => {
const dispatch = useDispatch();
const navigate = useNavigate();
const [isLoggingOut, setIsLoggingOut] = useState(false);
const [error, setError] = useState(null);
const handleLogout = async () => {
try {
await axios.post('http://localhost:3000/users/logout',{}, {
withCredentials: true,
});
dispatch(clearUser());
navigate("https://stackoverflow.com/");
} catch (error) {
console.error('Logout error:', error);
setError('An error occurred while logging out.');
}
};
return (
<div>
{/* Logout button */}
<CiLogout onClick={handleLogout} >
logout
</CiLogout>
{error && <p>Error: {error}</p>}
</div>
);
};
export default Logout;
**
and the logout Controller**
const logout = async (req, res) => {
try {
if (!req.isAuthenticated()) {
return res.status(401).json({ error: "Not logged in" });
}
try {
const sessionId = req.sessionID;
await pool.query("DELETE FROM sessions WHERE sid = $1", [sessionId]);
} catch (dbErr) {
console.error("Error deleting session from database:", dbErr);
// Decide whether to proceed with session destruction or return an error
}
// Destroy the session
await req.session.destroy();
res.status(200).json({ message: "Logout successful" });
} catch (err) {
console.error("Error during logout:", err);
return res.status(500).json({ error: "Internal Server Error" });
}
};
Here is my Express app aswell
const express = require("express");
const bodyParser = require("body-parser");
const session = require("express-session");
const pgSession = require("connect-pg-simple")(session);
const passport = require("passport");
const path = require("path");
require("dotenv").config();
const cors = require("cors");
// Import the pool module you created
const pool = require("./db");
const productsRoutes = require("./routes/productRoutes");
const usersRoutes = require("./routes/userRoutes");
const cartRoutes = require("./routes/cartRoutes");
const orderRoutes = require("./routes/orderRoutes");
const app = express();
const sess = {
store: new pgSession({
pool,
tableName: "sessions",
}),
secret: 'keyboard cat',
resave: false, // Add this line to explicitly set resave to false
saveUninitialized: false, // Add this line to explicitly set saveUninitialized to false
cookie: {
maxAge: 10 * 60 * 1000,
secure: process.env.NODE_ENV === 'production',
httpOnly: true,
sameSite:'none'
},
}
app.use(session(sess))
app.use(express.json({limit: '50mb'}));
app.use(express.urlencoded({limit:'50mb', extended: true }));
app.use(passport.initialize());
app.use(passport.session());
const corsOptions = {
origin: 'http://localhost:5173', // Replace with the origin of your frontend application
methods: 'GET,HEAD,PUT,PATCH,POST,DELETE',
credentials: true, // Allow credentials
preflightContinue: false,
optionsSuccessStatus: 204,
};
app.use(cors(corsOptions));
app.use("/users", usersRoutes);
app.use("/images", express.static(path.join(__dirname, "public/images")));
app.use("/products", productsRoutes);
app.use("/cart", cartRoutes);
app.use("/orders", orderRoutes);
app.use((err, req, res, next) => {
console.error(`Error in ${req.method} ${req.url}`);
console.error(err.stack);
res.status(500).send("Something went wrong!");
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`);
});
I’d make your logout endpoint not return a 401
For the postman its seems to be holding on to session. Try deleting the cookie in postman before retrying.