0

I'm trying to create signup Form using React, Express and MongoDB. I succeffuly implemented the post request and saved the user data in the database.

However,though the user is saved in the database, I failed to store ( see it the browser ) the jwt token using res.cookie('jwt',token).

I have a simple form made in React:


type Props = {
    children: React.ReactNode;
};
export const SignupLayout = ({ children }: Props) => {
    const user = {
        email: 'alexy@gmail.com',
        username: 'alexladies',
        password: 'pasrfsfsdfgfdsd',
        securityQuestion: "father's name",
        securityAnswer: 'jhon',
        joinedDate: '12-12-2023',
    };
     

    const handleSignup = async (event: React.SyntheticEvent) => {
        event.preventDefault();

        // The problem is here
        await fetch('http://localhost:3000/signup', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify(user),
        })
            .then((reponse) => reponse.json())
            .then((json) => console.log(json))
            .catch((err) => console.log(err));
    };
    return (
        <form
            onSubmit={handleSignup}
            method='post'
            action='/signup'
            className='sm:px-20 md:w-2/3 md:px-12 lg:w-1/2 lg:px-4 lg:my-4 xl:mt-16 xl:w-1/3 xl:px-16 mx-auto bg-white rounded-2xl py-10 text-center  '
        >
            {children}
        </form>
    );
};

My express server:


const User = require('../../models/user');
const { handleError } = require('./error');
const { createToken } = require('../utils/token');

const getSignup = (req, res) => {
    // It stores the cookie in the browser succesfully
    res.cookie('name', 'value');
    res.send('ok');
};

const postSignup = async (req, res) => {
    // It failed to store the cookie in the browser !
    const {
        email,
        password,
        username,
        securityQuestion,
        securityAnswer,
        joinedDate,
    } = req.body;

    const user = new User({
        email,
        password,
        username,
        securityQuestion,
        securityAnswer,
        joinedDate,
    });

    await user
        .save()
        .then(() => res.cookie('jwt', createToken(user._id)))
        .then(() => res.status(200).json(user._id))
        .catch((err) => {
            res.status(400).json(handleError(err));
        });
};

module.exports = { getSignup, postSignup };

I have tried to add:

 credentials:'include'

But it does not work.

Sreenshot

enter image description here

1 Answers1

0

After hours of debugging, I found the issue was in the server cors options.

Because I have different origins:

  1. Client: http://localhost:5173/
  2. Server: http://localhost:3000

It must configure cors in the server before sending responses to the client.

The configuration should be like this :

app.use(
    cors({
        credentials: true,
        origin: 'http://localhost:5173',
        exposedHeaders: ['SET-COOKIE'],
    })
);

It allows the server to expose the cookie in the Header response and send it back to the browser when it receives a request from the client ( React ).

In our client ( React ) we have to set credentials:'important :


const response = await fetch('http://localhost:3000/signup', {
            credentials: 'include', // Important
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                Accept: 'application/json',
                'Access-Control-Allow-Origin': 'http://localhost:3000',
            },
            body: JSON.stringify(user),
        });

It allows it to set the cookie sent back in cross-origin requests.