kwak
kwak

Reputation: 151

Why isn't the express session cookie being stored on the browser's cookie storage on production, but it works on localhost?? (express + react)

I created a test react app which is deployed at vercel and the server is at render.com. To solve cross-site cookie problems I set the same domain on both (app.mydomain.online for the app, and api.mydomain.online for the API). Now, when i look at the cookie in the header, no errors are showing up. However, The cookie still not getting stored.

server is created via npm init. react is created via npm create-react-app.

this is my sample code.

server

const express = require("express");
const cors = require("cors");
const session = require('express-session');
const app = express();
require('dotenv').config();

const PORT = process.env.PORT;

app.use(express.json());
app.use(cors({
    origin: 'https://app.myDomain.online',
    methods: ["POST", "PUT", "GET", "OPTIONS", "HEAD"],
    credentials: true
}));

const oneDay = 1000 * 60 * 60 * 24;
app.set('trust proxy', 1) // trust first proxy
app.use(session({
  secret: 'keyboard cat',
  resave: false,
  saveUninitialized: true,
  cookie: { secure: true, sameSite: 'none' }
}));

app.get('/createSession', (req, res) => {
    req.session.user = 'user';
    res.send('new session is created');
});

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

app.get('/getSession', (req, res) => {
    if(req.session.user){
        res.send('active');
    }else{
        res.send('not active');
    }
});

app.listen(PORT, () => {
    console.log(`The server is running on port ${PORT}`);
});

react

import React from 'react'
import { useEffect } from 'react';
import Axios from 'axios';

function Test() {
    
    useEffect(() => {
        Axios.get(' https://api.myDomain.online/createSession',
                  { withCredentials: true }
        );
    }, []);
    
    

    return (
        <div>Test</div>
    )
}

export default Test;

Upvotes: 4

Views: 1240

Answers (2)

kwak
kwak

Reputation: 151

I actually found a solution a few days ago, It turned out that the cookie was being blocked was because its domain was too similar to the server's. I was able to fix the it by removing the api from the cookie's domain as cookie: { domain: '.domain.com' }. This is my new code bellow.

const oneDay = 1000 * 60 * 60 * 24;
const APP_SESSION = session({
    secret: 'secrete',
    resave: false,
    saveUninitialized: true,
    name: 'session',
    cookie: {
        secure: true,
        sameSite: 'none'
        maxAge: oneDay,
        domain: '.domain.com'
    }
});

Upvotes: 0

Phil
Phil

Reputation: 164897

From the documentation for express-session...

cookie.expires

Specifies the Date object to be the value for the Expires Set-Cookie attribute. By default, no expiration is set, and most clients will consider this a “non-persistent cookie” and will delete it on a condition like exiting a web browser application.

The docs go on to prefer the maxAge property to control this. Choose a time frame that makes sense for your application. For example, 1 week...

app.use(
  session({
    secret: "keyboard cat",
    resave: false,
    saveUninitialized: true,
    cookie: { secure: true, sameSite: "none", maxAge: 7 * 24 * 60 * 60 * 1000 },
  })
);

Upvotes: 2

Related Questions