0

I am trying to verify a logged In user token in my MERN. However, I am getting "undefined" on client-side as API response.

When I hit the 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.

But when I do the same in my react app, the token returns undefined. I have spent hours debugging it but unable to figure it out.

Please I need help.

Here is my React (client side) code:

    axios.defaults.withCredentials = true;

    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;
        return data;
      };
      React.useEffect(() => {
        sendRequest().then((response) => console.log(response.data));
      }, []);
    
      return <div>Welcome</div>;
    }

Here is my login endpoint.

        exports.loginUser = async (req, res) => {
          const { name, password } = req.body;
        
          let existingUser;
          try {
            existingUser = await User.findOne({ name: name });
          } catch (err) {
            return new Error(err);
          }
          if (!existingUser) {
            return res.status(400).json({ status: "fail", message: "user not found" });
          }
        
          const isPasswordCorrect = bcrypt.compareSync(password, existingUser.password);
          if (!isPasswordCorrect) {
            return res
              .status(400)
              .json({ status: "fail", message: "invalid email or password" });
          }
          const token = jwt.sign({ id: existingUser._id }, process.env.JWT_SECRET, {
            expiresIn: process.env.JWT_EXPIRES_IN,
          });
        
          res.cookie("jwt", token, {
            path: "/",
            expires: new Date(Date.now() + 1000 * 70),
            httpOnly: true,
            sameSite: "lax",
          });
        
          return res
            .status(200)
            .json({ message: "Succesfully loggedIn", user: existingUser, token });
        };

Here is my verifyToken endpoint

     exports.verifyToken = (req, res, next) => {
       const cookies = 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();
        };

router.route("/verify").get(verifyToken, getUser);//endpoint

exports.getUser = async (req, res, next) => {
  const userId = req.id;
  let user;
  try {
    user = await User.findById(userId, "-password");
  } catch (err) {
    return new Error(err);
  }

  if (!user) {
    return res.status(404).json({ status: "fail", message: "user not found" });
  }
  
  return res.status(200).json({ user });
};
oladimeji
  • 71
  • 1
  • 10
  • Can you check whether cookies are being stored correctly on client-side and being passed in requests? – EternalObserver Dec 25 '22 at 08:28
  • @EternalObserver I can see the token in the Headers of my login route "Set-Cookie:jwt=xxxxx". How else can i check if the cookie is stored correctly – oladimeji Dec 25 '22 at 08:37
  • You can check it in application section in your browser's dev-tools. But if the cookie is being passed in request headers, then maybe it's not an issue. – EternalObserver Dec 25 '22 at 08:44
  • You should return something in your `verifyToken` function. A 200 OK response or something depending on your business logic and API contracts. – EternalObserver Dec 25 '22 at 08:45
  • @EternalObserver, the "next()" in verifyToken is used to return the user details in another endpoint (getUser). Here is the route--- "router.route("/verify").get(verifyToken, getUser);" – oladimeji Dec 25 '22 at 09:06
  • can you verify anywhere in the services or routes which you have written for `verify` you're returning a response? Since client is receiving `undefined`, it looks like you're not returning a response somewhere in your application. Default return value of a function in Node is undefined. – EternalObserver Dec 25 '22 at 09:16
  • http only cookie are not visible in dev tools you can check if the cookie exist or not by trying it to set it by the same name you set your cookie if you cannot set it the then cookie exist check this https://stackoverflow.com/questions/9353630/check-if-httponly-cookie-exists-in-javascript – Jagadish Shrestha Dec 25 '22 at 16:57

0 Answers0