0

I am using JWT token for authentication in my MERN app. when i click on this endpoint "http://127.0.0.1:1000/api/v1/users/login" in postman to login a user and this endpoint "http://127.0.0.1:1000/api/v1/users/verify" to verify a user's token, the token is returned. However, when i do the same operation in my react frontend app, the token returns undefined. Please what am i doing wrong? Here is my React code. P.S the token is stored in the cookies.

function Welcome() {
  const [user, setUser] = useState("");
  const sendRequest = async () => {
    const res = await axios
      .get("http://127.0.0.1:1000/api/v1/users/verify", {
        withCredentials: true,
      })
      .catch((err) => console.log(err));

    const data = await res.data;
    console.log("RESPONSE", data);
    return data;
  };
  React.useEffect(() => {
    sendRequest().then((data) => console.log(data));
  }, []);
  console.log(user);
  return <div>Welcome</div>;
}

Here is the Verify token code in my express app

exports.verifyToken = async (req, res, next) => {
  const cookies = await req.headers.cookie;
 
  const token = cookies.split("=")[1];


  if (!token) {
    res.status(404).json({ message: "no token found" });
  }

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

    req.id = user.id;
  });
  next();
};
oladimeji
  • 71
  • 1
  • 10
  • 1
    `next()` needs to go inside the callback, otherwise it runs first. `jwt.verify` is asynchronous, hence the callback. – ggorlen Dec 23 '22 at 01:05

3 Answers3

0

User cookie parser

const express = require("express");
const app = express();
const cookieParser = require("cookie-parser");

app.use(express.json());

app.use(cookieParser());

app.get("/", (req, res) => {
  res.setHeader("Set-Cookie", "name=langesh;SameSite=None;");

  res.send("hello");
});

app.get("/get-cookie", (req, res) => {
  res.send(req.cookies);
});

app.listen(9000);

output

{name : "langesh"}
Langesh
  • 76
  • 6
  • Hi @Langesh i am able to retrieve the token in cookie in Postman. However, when i do the same in my react app, i get undefined – oladimeji Dec 25 '22 at 07:39
  • You can't sent cookies to different domains. I have updated the code. Take a look. – Langesh Dec 25 '22 at 09:09
0

I personally don't have much experience with axios, I prefer fetch() method, it works perfectly.

That said, I think this issue could arise because token isn't identified in the request. Try adding headers: { Authorization: `Bearer ${token}`} to your get method and see if it is fixed.

Your code should look like :

axios.get("http://127.0.0.1:1000/api/v1/users/verify", {
  headers: {
    Authorization: `Bearer ${token}`
  },
  withCredentials: true,
})
se1ko
  • 31
  • 4
0

If the token is set with the parameter httpOnly as True (by your backend code as below), your frontend javascript cannot access the token as the HttpOnly flag prevents JavaScript access to the cookie, making it more challenging for an attacker to access the JWT through XSS..

               res.cookie('jwt', 
                        accesstoken, 
                        { 
                          path: "/",
                          httpOnly: true,
                          secure: true,
                          sameSite: 'strict'
                    
                        })

If you want to check if the token is valid when the user is on a particular page and then take necessary steps, you can send a request to validate the token to the backend as any request from the website will consist of the token stored in the cookie. And if the backend responds that the token is valid, you can then take the necessary step.

By doing this you delegate the work of validating the token to the backend.