0

I'm running into this issue:

  • localhost:3000 (React App)
  • localhost:9000 (Nodejs Backend)

I was able to send the request from postman and receive the cookies there, however in the frontend when I check for the cookies in the browser there is nothing.

The cookies are not visible under the Application > Cookies tab.

The code I use for handing signups and sending the cookie:

// requirements
const User = require('../models/User');
const jwt = require('jsonwebtoken');

// handle errors
const handleErrors = (err) => {
    console.log(err.message, err.code);
    let errors = { first_name: '', last_name: '', email: '', password: '' };

    // duplicate error code
    if (err.code === 11000) {
        errors.email = 'That email is already registered';
        return errors;
    }

    // validation errors
    if (err.message.includes('User validation failed')) {
        Object.values(err.errors).forEach(({ properties }) => {
            errors[properties.path] = properties.message;
        });
    }
    return errors;
}

const maxAge = 3 * 24 * 60 * 60;
const createToken = (id) => {
    return jwt.sign({ id }, 'Dummy Secret', {
        expiresIn: maxAge
    });
}

// module exporting

module.exports.signup_post = async (req, res) => {
    const { first_name, last_name, email, password } = req.body;
    
    try {
        const user = await User.create({ first_name, last_name, email, password });
        const token = createToken(user._id);
        res.cookie('jwt', token, { httpOnly: true, maxAge: maxAge * 1000 });
        res.status(201).json({ user: user._id });
    }
    catch (err) {
        const errors = handleErrors(err);
        res.status(400).json({ errors });
    }
};

If anyone could guide me on what to do I'd be grateful

UPDATE: I did some testing and the results were as follows: when I ran this code in the main app.js on the backend and send a request from the front end, the cookies were still messed up, so it might very well be the frontend.

app.get('/set-cookies', (req, res) => {
    res.cookie('newUesr', false);
    res.cookie('isEmployee', true, { maxAge: 1000 * 60 * 60 * 24, httpOnly: true});

    res.send('you got the cookies!');
});

app.get('/read-cookies', (req, res) => {
const 

});

But when I do it through my controllers in the previously shown code it gets stuck in set cookies as shown in this picture

Nomas
  • 31
  • 1
  • 6
  • I've been looking around, googling, and so on and I feel like I might be missing a step in the front end, however I can't find anything to help :/ – Nomas Feb 08 '22 at 15:57
  • I don't believe you can access httponly cookies in react since they are on the server. – Sean Feb 08 '22 at 15:59
  • An HttpOnly cookie means that it's not available to scripting languages like JavaScript. – Vitaliy Rayets Feb 08 '22 at 15:59
  • In developer tab there's a network tab, if you select the DOC and refresh the page, you can see your domain there click it and if there's no cookie present then you have not sent the response back to the user properly. – BGPHiJACK Feb 08 '22 at 16:04
  • User should be offered a cookie when first creating it, then following refreshes user will offer up their cookie unless server wants to change it. – BGPHiJACK Feb 08 '22 at 16:05
  • @BGPHiJACK ah I do see the cookie is there, is it normal that I can't see it under the application tab? – Nomas Feb 08 '22 at 16:10
  • You should see that in the browser `application tab > cookie`. – ikhvjs Feb 08 '22 at 16:16
  • @ikhvjs That's the issue I don't see it there but I did see it __once__ where BGPHiJACK mentioned it but not anymore :/ – Nomas Feb 08 '22 at 16:22
  • They may had became filtered out because they are no longer valid. This happens when the cookie you sent in the request does not match what the server responds with. The server could had deleted the cookie or re-generated a new ID but the client will keep the list of cookies till cleared by browser. – BGPHiJACK Feb 08 '22 at 16:36
  • There's a few potential problems, let's just be sure though you're not doing any load-balancing as this looks in-memory and only one server would be aware of the session till you opened a redis/database solution. – BGPHiJACK Feb 08 '22 at 16:41
  • @BGPHiJACK Where do I start/How do I do that? – Nomas Feb 08 '22 at 16:43
  • Well I don't see a cookie parser, which is generally required for express. Try installing that first and seeing if it's just an issue on when the user makes a request express can't read it.https://expressjs.com/en/resources/middleware/cookie-parser.html – BGPHiJACK Feb 08 '22 at 16:46
  • Be sure to apply app.use(cookieParser()) above all your get/post routes to be sure it's used by all of your routes instead of a few. If you place it below a route, that/those routes won't use the parsing. In this case, it'd not go in this code but your main project where all the routing takes place. – BGPHiJACK Feb 08 '22 at 16:49
  • @BGPHiJACK I do have `app.use(cookieParser());` in the app.js and the cookies are received through POSTMAN just not the browser. – Nomas Feb 08 '22 at 17:05
  • Okay so back to they may had became filtered, go check for that. Server would had sent a response with a cookie but if it didn't store this properly or keep track of it, next time user makes request with the cookie it's invalid and filtered out. – BGPHiJACK Feb 08 '22 at 17:15
  • @BGPHiJACK How would I check for that?? apologies for asking too many questions, this is my first time ever setting up a backend. – Nomas Feb 08 '22 at 17:22
  • I've actually just noticed something, I get the cookie in the **set cookie** in the fetch request for signup but not in the cookie on localhost, here is a [picture](https://cdn.discordapp.com/attachments/938088944397074432/940659778970075167/unknown.png) – Nomas Feb 08 '22 at 17:27
  • I explained above the section check for filtered out request cookies, they're hidden usually but will reveal if you had been given a cookie and server is not accepting it. Beyond that not much here is helpful, your session handling could be screwing all this up and it's not clear here, project seems a bit over-developed to determine. – BGPHiJACK Feb 08 '22 at 17:47

2 Answers2

3

I was able to solve the issue by doing those steps:

  1. Making sure the fetch request has the withCredntials: true and credentials: 'include', so the fetch request would be like this:
    fetch("http://localhost:9000/testAPI", {
                withCredntials: true,
                credentials: 'include'
    })

Keep in mind this is only working with GET requests not POST requests without the 2nd step.

  1. For POST requests being blocked by cors, just make sure you have this line in your backend after you've required cors of course app.use(cors({credentials: true, origin: true})); using * or http://localhost:3000 (regardless of port number) instead of true seems to give the error.

NOTE: According to @ikhvjs the withCredntials: true is not required, however I'm yet to try this so try at your own risk.

Thank you all for the help :D

Nomas
  • 31
  • 1
  • 6
1

Here's a helpful link for understanding httpOnly cookies and alternate methods. How to get HTTP-only cookie in React?

Sean
  • 1,368
  • 2
  • 9
  • 21