skip to Main Content

I’m working on a MERN stack application (MongoDB, Express, React, Node.js). On the frontend, I use Axios for HTTP requests. The issue arises when I try to send a JWT in the Authorization header — the server responds with a 401 Unauthorized error.

Here’s what I’ve done so far:

I retrieve the token from localStorage on the frontend.
I send the token in the Authorization header in the format Bearer <token>.
The backend uses jsonwebtoken to verify the token.
Despite these steps, the server rejects the request. I’d appreciate help identifying the issue.

Frontend Code:

import React, { useEffect } from "react";
import axios from "axios";

const ShowDish = () => {
useEffect(() => {
const fetchDishes = async () => {
try {
const token = localStorage.getItem("token");
if (!token) {
throw new Error("Token is missing! Please log in again.");
}

        const response = await axios.get("http://localhost:5000/api/dishes", {
          headers: {
            Authorization: Bearer ${token},
          },
        });
    
        console.log("Dishes:", response.data);
      } catch (error) {
        console.error("Error fetching dishes:", error);
      }
    };
    
    fetchDishes();

}, []);

return <div>Loading dishes...</div>;
};

export default ShowDish;

Backend Code:

const jwt = require("jsonwebtoken");
const express = require("express");
const app = express();

const JWT_SECRET = "supersecretkey"; // (Store this in a .env file)

app.use(express.json());

// Generate token during login
app.post("/api/login", (req, res) => {
const { email, password } = req.body;

// Example user (in a real app, validate against the database)
const user = { id: "123", email, role: "user" };

const token = jwt.sign(
{ id: user.id, email: user.email, role: user.role },
JWT_SECRET,
{ expiresIn: "1h" }
);

res.json({ token });
});

Middleware


const jwt = require("jsonwebtoken");

const verifyToken = (req, res, next) => {
const token = req.cookies.token;

if (!token) {
return res.status(401).json({ message: "Not authenticated" });
}

try {

    const decoded = jwt.verify(token, process.env.JWT_SECRET);
    req.user = decoded; 
    next();

} catch (err) {
return res.status(403).json({ message: "Invalid token" });
}
};

const authenticateToken = (req, res, next) => {
const authHeader = req.headers["authorization"];
const token = authHeader && authHeader.split(" ")[1]; 
if (!token) {
return res.status(401).json({ message: "Token is missing" });
}

jwt.verify(token, process.env.JWT_SECRET, (err, user) => {
if (err) {
return res.status(403).json({ message: "Invalid token" });
}
req.user = user;
next();
});
};

Protected endpoint:

app.get("/api/dishes", verifyToken , (req, res) => {
res.json({ message: "Here are the dishes!", user: req.user });
});

const PORT = 5000;
app.listen(PORT, () => console.log(Server is running on port ${PORT}));

Expected Behavior:

When sending a GET request to http://localhost:5000/api/dishes with a valid token in the Authorization header, I expect to receive a response with data (e.g., the list of dishes).

Actual Behavior:

AxiosError: Request failed with status code 401

What I’ve Tried: Verified the token is correct by decoding it on jwt.io. Confirmed the token is being sent in the Authorization header as Bearer <token>. Double-checked the backend middleware for verifying the token. What could be causing this issue? Thank you for any guidance! And I apologize for my bad English, I had to use transtalor

2

Answers


  1. It seems like you are first trying to retrieve the token from cookies, and you return 401 if it’s not there:

    const token = req.cookies.token;
    
    if (!token) {
    return res.status(401).json({ message: "Not authenticated" });
    }
    

    Maybe you should not end the middleware code here, but instead let it pass and check the headers, like you are doing below.

    Login or Signup to reply.
  2. You are passing the token in the header from the frontend, so you should retrieve them from the header as well from the backend instead of cookies

    On your "/api/dishes" route, you are using verifyToken method to verify the token from request cookies instead of header.

    You should replace the verifyToken method on the "/api/dishes" route with authenticateToken

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search