Search code examples
javascriptreactjsnode.jsexpresscookies

How to send Cookie from Server to the Users Browser


I am trying to understand cookies and their working So I am trying to send the cookie from the server and set it to the user browser But, in the inside developer tools--> application-->cookie I cant see my cookie present there and I cant understand why

This is a simple react app This is my App.js

function App() {

  async function Check() {
    const response = await fetch("http://localhost:5000/check", {
      method: "GET",
    });
    const data = await response.text();
    console.log(data);
  }

  return (
    <div className="App">
      <button onClick={Check}>CheckCookie</button>
    </div>
  );
}

export default App;

This is my Server

const express = require('express');
const cors = require('cors');
const app = express();

app.use(express.json());
app.use(express.urlencoded({extended:false}));

app.use(cors());

app.get('/', (req,res)=>{
    res.send("Website Server");
})

app.get('/check', cors(), async (req, res) => {
  res.cookie('cookieName', 'SUCCESSFULL', {
      maxAge: 900000,
      httpOnly: false,
      secure: false,
      sameSite: 'Strict',
      domain: 'localhost'
   });
    res.send('Cookie set successfully');
});
  

app.listen(5000, () => console.log('Running on port 5000'));

Onclicking "CheckCookie" button "Cookie set successfully" is logged in the console but when I check developer tools--> application-->cookie I cant see my cookie there enter image description here

enter image description here

Instead when I open networks tab there I can see the cookie sent in response enter image description here

Why is this happening I can't understand, how doe's this work, please help.


Solution

  • You need to change both sides (server.js and App.js)

    Cookie handling

    The react-cookie simplifies cookie handling for max-age handling.

    There's no need to parse response headers from the server to extract the expiration time and full control over cookie management on the client-side, allowing you to easily adjust expiration times as needed without server-side dependencies.

    Confirm expires in client UI.

    When the "Set Cookie" button is clicked, we calculate the expiration time (expires) based on the current time (Date.now()) plus the desired duration (900 * 1000 milliseconds).

    Server provides CORS

    The corsOptions defines the CORS options to be used by the CORS middleware. sets up the CORS middleware with the specified options.

    The server will now allow requests from 'http://localhost:3000' (the origin of your React app) and will enable credentials (cookies) for these requests.

    const corsOptions = {
      origin: 'http://localhost:3000', // your React URL
      credentials: true // Enable credentials (cookies, HTTP authentication)
    };
    
    app.use(cors(corsOptions));
    

    Express Server

    As server.js

    const express = require('express');
    const cors = require('cors');
    const app = express();
    
    app.use(express.json());
    app.use(express.urlencoded({ extended: false }));
    
    // Allow requests only from your React app's origin
    const corsOptions = {
      origin: 'http://localhost:3000',
      credentials: true // Enable credentials (cookies, HTTP authentication)
    };
    
    app.use(cors(corsOptions));
    
    app.get('/', (req, res) => {
      res.send('Website Server');
    });
    
    app.get('/check', async (req, res) => {
        res.cookie('cookieName', 'SUCCESSFULL', {
            maxAge: 900000,
            httpOnly: false,
            secure: false,
            sameSite: 'Strict',
            domain: 'localhost'
        });
        res.send('Cookie set successfully');
    });
    
    app.listen(5000, () => console.log('Running on port 5000'));
    

    Client Side

    App.js

    import React, { useState } from 'react';
    import { useCookies } from 'react-cookie';
    
    function App() {
      const [cookies, setCookie] = useCookies(['cookieName']);
      const [cookieStatus, setCookieStatus] = useState('');
      const [expiresAt, setExpiresAt] = useState('');
    
      const handleCheckCookie = async () => {
        try {
          const response = await fetch('http://localhost:5000/check', {
            method: 'GET',
            credentials: 'include' // Include cookies in the request
          });
    
          if (response.ok) {
            const expiresInMs = response.headers.get('max-age') * 1000;
            const now = new Date();
            const expires = new Date(now.getTime() + expiresInMs);
    
            document.cookie = `cookieName=SUCCESSFULL;expires=${expires.toUTCString()};path=/;`;
    
            setCookieStatus('Cookie set successfully');
            setExpiresAt(expires.toLocaleString());
          } else {
            setCookieStatus('Failed to set cookie');
            setExpiresAt('');
          }
        } catch (error) {
          console.error('Error:', error.message);
          setCookieStatus('Failed to set cookie');
          setExpiresAt('');
        }
      };
    
      return (
        <div>
          <button onClick={handleCheckCookie}>Check Cookie</button>
          <p>{cookieStatus}</p>
          {expiresAt && <p>Cookie Expires At: {expiresAt}</p>}
        </div>
      );
    }
    
    export default App;
    

    Result

    enter image description here