1

I am creating a React, Nodejs, MySQL project and I have implemented the login functionality for users.

Now I want the application to be able to identify the user and hence I have used jwt and am storing it in the cookie.

Now in the backend of the login code, I am trying to set the res.cookie this way

const login = (req, res) => {
  //CHECK USER

  const q = "SELECT * FROM users WHERE username = ?";

  db.query(q, [req.body.username], (err, data) => {
    if (err) return res.status(500).json(err);
    if (data.length === 0) return res.status(404).json("User not found!");

    //Check password
    const isPasswordCorrect = bcrypt.compareSync(
      req.body.password,
      data[0].password
    );

    if (!isPasswordCorrect)
      return res.status(400).json("Wrong username or password!");

    const token = jwt.sign({ id: data[0].id }, "jwtkey");
    const { password, ...other } = data[0];

    res.cookie('token', token, {httpOnly: true}).status(200).json(other)
  });
};

With this code, I am able to see a Set-cookie in the response headers but unable to see the cookie in the cookie section in applications tab.

But when I instead do this send the token to the frontend,

const login = (req, res) => {
  //CHECK USER

  const q = "SELECT * FROM users WHERE username = ?";

  db.query(q, [req.body.username], (err, data) => {
    if (err) return res.status(500).json(err);
    if (data.length === 0) return res.status(404).json("User not found!");

    //Check password
    const isPasswordCorrect = bcrypt.compareSync(
      req.body.password,
      data[0].password
    );

    if (!isPasswordCorrect)
      return res.status(400).json("Wrong username or password!");

    const token = jwt.sign({ id: data[0].id }, "jwtkey");
    const { password, ...other } = data[0];

    return res.json({
      status: 200,
      token: token,
      other: other,
    });
  });
};

And then set the cookie from the frontend like this,

  const handleSubmit = async (e) => {
    e.preventDefault();
    try {
      const res = await axios.post(
        "http://localhost:8080/api/auth/login",
        inputs,
        {
          headers: {
            Accept: "application/json",
            "Content-Type": "application/json",
          },
        }
      );
      const data = await res.data;
      if (data.status === 200) {
        document.cookie = `token=${data.token}; path=/`; // Set the token as a cookie
        navigate("/");
      }
    } catch (error) {
      setError(error.response.data);
    }
  };

It works and I can see the cookie in the cookie section of the applications tab.

My question is whether it is safe to set cookie in this way? If no, then what other method can I use since res.cookie is not working or am I doing anything incorrect in res.cookie?

Shadow
  • 33,525
  • 10
  • 51
  • 64
  • 1
    There is not much difference here. I guess that the cookie isn't set in the first example because you didn't send the request correctly. `credentials` option must be present to save the cookies using `axios` Please include your frontend part as well. – Konrad Jun 30 '23 at 10:09
  • I have already included the handleSubmit function of the frontend part. Should I include anything else? – Vayun Ekbote Jun 30 '23 at 10:28
  • Does this answer your question? [Does Axios support Set-Cookie? Is it possible to authenticate through Axios HTTP request?](https://stackoverflow.com/questions/52549079/does-axios-support-set-cookie-is-it-possible-to-authenticate-through-axios-http) – Konrad Jun 30 '23 at 10:31
  • Hey @Konrad I now want to clear the cookie and have written this function for that purpose, ``` const logout = (req, res) => { res.clearCookie("token", { sameSite: "none", secure: true, }); return res.status(200).json("User has been logged out."); }; ``` But it is not working. I have already included the credentials in the post request. – Vayun Ekbote Jun 30 '23 at 12:01

1 Answers1

0

I simply added an withCredentials: true to my request like https://stackoverflow.com/users/5089567/konrad mentioned in a comment and it worked fine for me