Question

cookie sent from node backend but not shown on application tab

I am sending cookie in response from node backend to my frontend after jwt signing. In the network tab on frontend , the set-cookie is visible and the cookie is been shown , but in the application tab , the cookie is not getting shown. Why is it?

Backend Function Code for sending cookie :

import jwt from 'jsonwebtoken'

export const generateTokenAndSetCookie = (userId , res)=>{
    const token = jwt.sign({userId} , process.env.JWT_SECRET , {
        expiresIn : '15d', 
    } )
    res.cookie("jwt" , token , {
        httpOnly: false,
        secure: true,
        sameSite:'none'
    })
}

CORS Code :

app.use(cors({credentials : true , origin : 'http://localhost:3000'}));

Frontend Code for sending POST request for Login :

const handleSubmit = async (e) => {
        e.preventDefault();
        // console.log(formData);
        if (!formData.password || !formData.username) {
            toast("Please Fill All the Fields !");
            return;
        }

        try {
            setLoading(true);
            const res = await fetch(`${PROXY_URL}/api/auth/login`, {
                method: "POST",
                headers: {
                    "Content-Type": "application/json",
                },
                body: JSON.stringify(formData),
            });
    
            const data = await res.json();
            if (!res.ok){
                toast.error(data.error || "Failed to Login");
                setLoading(false);
                return;
            }
            setLoading(false);
            setIsError(false);
            // console.log(data);
            console.log(document.cookie);
            toast.success("User Logged In Successfully !");
            setFormData({
                username: "",
                password: "",
            })
        } catch (error) {
            setIsError(true);
            console.log(error);
        }
    };

Network Tab Picture :

Network tab pic

Application tab Picture at same time:

application Tab pic

What to do ?

 3  111  3
1 Jan 1970

Solution

 2

This very often happens to me as well. Can you try to rewrite your api call to have credentials set to include.

          const res = await fetch(`${PROXY_URL}/api/auth/login`, {
                method: "POST",
                headers: {
                    "Content-Type": "application/json",
                },
                body: JSON.stringify(formData),
                credentials: 'include'
            });

I also think you might need to adjust the server to this:

    res.cookie("jwt" , token , {
        httpOnly: true, 
        // I think if server needs to set a cookie it must be httpOnly
        secure: process.env.NODE_ENV === 'production', 
        sameSite:'none'
    })

In addition these two posts might help you:

2024-07-13
Snake_py

Solution

 0

Set secure to false, perhaps using an environment variable to differentiate between your dev environment and production.

This is because the secure option ensures that the cookie is only sent over a secure connection which is indicated by "https://" in the address. In development mode, your connection is insecure since you're accessing from "http://localhost".

import jwt from 'jsonwebtoken'

export const generateTokenAndSetCookie = (userId , res)=>{
    const token = jwt.sign({userId} , process.env.JWT_SECRET , {
        expiresIn : '15d', 
    } )
    res.cookie("jwt" , token , {
        httpOnly: false,
        secure: process.env.NODE_ENV === 'production',
        sameSite:'none'
    })
}
2024-07-07
Alecia Vogel

Solution

 0

Looks like you're having some trouble setting up cookies, so let's just try with all the cookie options as I previously had a similar kind of issue.

// Set cookie options
  const cookieOptions = {
    // httpOnly: true, // Prevents client-side access to the cookie
    sameSite: "None", // Allows cross-origin requests to include the cookie
    secure: true, // Ensures the cookie is only sent over HTTPS
    domain: "192.168.99.62", // Set to your server's domain, do not type localhost, use your IP instead
    path: "/", // Cookie is valid for all routes
    expires: new Date(Date.now() + 3600000), // Cookie expires in 1 hour (adjust as needed)
  };

  // Set the cookie
  res.cookie("authToken", jwtToken, cookieOptions);
2024-07-09
Sowmo0509

Solution

 0

It seems like your frontend and backend are not on the same domain (or port). When you set a cookie from your backend, it places it on the domain of your backend. To use a different domain, you have to specify it explicitly:

res.cookie("jwt" , token , {
        httpOnly: false,
        secure: true,
        sameSite:'none',
        domain: 'http://localhost:3000', 
    })
2024-07-13
arnaud

Solution

 0

I got my answer. While sending the fetch request to the server, I was not passing the header :

headers: {
    "Content-Type": "application/json",
},

After passing this header, everything worked fine.

2024-07-15
Aditya Nagare