jonasschmedtmann / complete-node-bootcamp

Starter files, final projects and FAQ for my Complete Node.js Bootcamp
https://www.udemy.com/nodejs-express-mongodb-bootcamp/?couponCode=GITHUB515
3.07k stars 3.59k forks source link

Section:12 Lesson 16 Browser not saving cookies #80

Open tamirazrab opened 3 years ago

tamirazrab commented 3 years ago

Able to login, response sent by API is good, cookies aren't getting stored by browser upon searching there are several things I've tried but none of them worked.

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

Axios with axios.defaults.withCredentials = true;

Still after that cookies aren't being stored.

nvispute commented 3 years ago
res.cookie("SSID", token, {
    expiresIn: new Date(
      Date.now() + process.env.JWT_COOKIE_EXPIRES_IN * 24 * 60 * 60 * 1000
    ),
    httpOnly: true,
    secure: req.secure || req.headers["x-forwarded-proto"] === "https",
  });

This code is responsible to setting the cookies to the response if no such response is sent by server then no cookie will be saved to the browser..

tamirazrab commented 3 years ago
res.cookie("SSID", token, {
    expiresIn: new Date(
      Date.now() + process.env.JWT_COOKIE_EXPIRES_IN * 24 * 60 * 60 * 1000
    ),
    httpOnly: true,
    secure: req.secure || req.headers["x-forwarded-proto"] === "https",
  });

This code is responsible to setting the cookies to the response if no such response is sent by server then no cookie will be saved to the browser..

Yes, thing is I can see cookie being sent, in POSTMAN, server is sending cookie but I can't see any cookie being saved in browser.

nvispute commented 3 years ago

Suggestion:

  1. Check if your browser setting is allowing cookies[this will differ from browser to browser]
  2. Check if your Front-end and Back-end are on same domain [assuming that you are using Server side rendering for the pages]
  3. If you are on Firefox then Refer to Using HTTP Cookies & Set-Cookie

If none of these work then you will need to share your code..

tamirazrab commented 3 years ago

Here's the code

Generating Cookie const signToken = id => { return jwt.sign({ id }, process.env.JWT_SECRET, { expiresIn: process.env.JWT_EXPIRES_IN }); };

const createAndSendTokenToClient = (user, statusCode, res) => {
  // payload -> storing only id
  const token = signToken(user._id);
  // automatically logging user in after new account has been created
  const cookieOption = {
    expires: new Date(
      Date.now() + process.env.JWT_COOKIE_EXPIRES_IN * 24 * 60 * 60 * 1000
    ),
    httpOnly: true
  };

  if (process.env.NODE_ENV !== 'development') cookieOption.secure = true;

  res.cookie('jwt', token, cookieOption);

  // hiding password from output
  user.password = undefined;

  res.status(statusCode).json({
    status: 'success',
    token,
    data: { user }
  });
};`

Login
`export const login = async (email, password) => {
  try {
    const res = await axios({
      method: 'POST',
      url: 'http://127.0.0.1:3000/api/v1/users/login',
      withCredentials: true,
      data: { email, password }
    });
    console.log(res);
    console.log(email, password);

    //  if successful then reloading page
    if (res.data.status === 'success') {
      window.setTimeout(() => {
        location.assign('/');
      }, 1000);
    }
  } catch (err) {
    console.log('err', err.response);
  }
};

After sending request, I can see success response being logged in and it redirects me to '/', it's just not storing cookie aside from cookie I think it maybe server which preventing browser from storing cookies? Maybe some headers that are being sent along with request which are preventing this, I don't have any idea about any of those headers, I'm attaching maybe you can spot something.

Headers headers

Edit: I was logging cookies through cookie parser every time there is request, though I've always been empty null object on console during browser, but when logged in with postman I could see cookie being logged. My guess is apart from code there is something else which is preventing browser from setting cookie even though server sent set-cookie,

tamirazrab commented 3 years ago

For any poor SOB who lands on this page as I did, 127.0.0.1 != localhost. If you are serving your site from localhost(port whatever) and making CORS requests to 127.0.0.1 (port whatever) cookies will not stick! Ensure to use either only localhost or only 127.0.0.1, but do not mix and match.

Finally this solved the problem I was using localhost in browser but in code I was making request to 127.0.0.1:300 const res = await axios({ method: 'POST', url: 'http://127.0.0.1:3000/api/v1/users/login', data: { email, password } });

As above quote says localhost != 127.0.0.1, make sure you are using the same. If it stills doesn't fix your problem try this it has some other solutions that might work for you.

Well it was pretty stupid mistake.

nvispute commented 3 years ago

Great job on Solving the issue... so it was a point number 2 from my suggestion.. although localhost & 127.0.0.1 are same the Key pair values when it comes to cookies do not match. to be precise

  1. for Access-Control-Allow-Origin: http://localhost:3000
  2. and for Set-Cookie: name=value; expires=Sun, 20-May-2018 21:43:05 GMT; Max-Age=3600; path=/; domain=localhost
tamirazrab commented 3 years ago

Now that you mentioned it was point 2 from your suggestions although it didn't made any sense at that time as both were on localhost but to be precise one was using typical URL while front end was using localhost. Maybe in future you can be specific in your second suggestion of localhost being not equal to 127... and aside from that thank you for your assistance. :)

official-commandcodes commented 11 months ago

Thanks for the solution @tamirazrab. It solves my issue right away after changing 127... to localhost... I have spent almost 2 hours figuring out the solution.

Jim124 commented 10 months ago

it works for me, thank you so much