'React+Expressjs Deployment

I am trying to Test if my build file is ok, Therefore what I did was to build client and move build directory to server. and in the index.js of backend => to open HTML of Build folder.(I do not know if this is right thing to do)

    app.get("/", function (req, res) {
  res.sendFile(__dirname + "/build/index.html");
});

Following folderStructure

-client
=>src(react Code)
-server
=>Build(which is from react 'npm run build')
=>BackendCode

I have implemented Login Routes one for Post login, and one for get login which is GET:

router.get("/login", async (req, res) => {
  console.log("getLogin ses.user:  ", req.session.user);
  console.log("getLogin ses.isLogIn?:  ", req.session.isLoggedIn);
  if (req.session.user) {
    return res.send({
      isLoggedIn: true,
      user: req.session.user,
      isAdmin: req.session.isAdmin,
      isVerified: req.session.isVerified,
      pwFlag: req.session.pwFlag,
    });
  } else {
    return res.send({ isLoggedIn: false });
  }
});

POST:

    router.post("/login", isNotLoggedIn, async (req, res) => {
    -- user find in DB and compare Password in db Logic...--
    if(user){ 
req.session.save((err) => {
            if (err) console.log(err);
            console.log("Session Saved!!!!: ", req.session);
            logger.info(`LOGIN POST/ ${req.session.user.email}`);
    
            return res.status(200).send({
              user: sessionUser,
              isAdmin: req.session.isAdmin,
              pwFlag: req.session.pwFlag,
            });
          })
})

with this two route, when i do router.post for login it works. REACT CODE=> Login Submit form

 const onLoginSubmit = async (e) => {
        e.preventDefault();
        setLoading(true);
        const req = { email, password };
        const res = await fetch(`${serverUrl}/login`, {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          credentials: "include", //to let cookie to go to server
          body: JSON.stringify(req),
        });
        const data = await res.json();
        if (res.ok) {
          console.log("login success");
          setLoginStat(true);
          setIsAdmin(data.isAdmin);
          setUser(data.user);
          setPwFlag(data.pwFlag);
    
          if (data.user) {
            setLoading(false);
            navigate("/");
          }
        } else {
          alert(data.message);
          setLoading(false);
        }
      };

and in the App.js of React,

useEffect(() => {
    checkLogin();
  }, []);
  async function checkLogin() {
    const res = await fetch(`${serverUrl}/login`, {
      method: "GET",
      headers: {
        Accept: "application/json",
        "Content-Type": "application/json",
      },

      credentials: "include",
    });
    try {
      const data = await res.json();
      console.log("App useEffect: ", data);
      if (res.ok) {
        console.log(data);
        setLoginStat(data.isLoggedIn);
        setUser(data.user);
        setIsAdmin(data.isAdmin);
        setIsVerif(data.isVerified);
        setPwFlag(data.pwFlag);
      }
    } catch (err) {
      setLoginStat(false);
    }
  }

so the Login Post works well it make me to go to main page. but when I go to different Page that has useEffect to fetch Data, and backend with middle where "isLoggedIn" : ex)router.get("/something", isLoggedIn, async(req,res)=>{...})

async function isLoggedIn(req, res, next) {
  console.log("MW => isLoggedIn:", req.session.user);
  console.log("MW => session:", req.session);

  if (req.session.isLoggedIn && req.session.user) {
    next();
  } else {
    return res.status(401).send({ message: "Did not login 🚫" });
  }
}

it say that MW => isLoggedIn: undefined session being gone. I really dont know why this is happening

To give Detail here is my index.js of server Setting:

const cors = require("cors");
const express = require("express");
const session = require("express-session");
...
app.use(
  session({
    store: MongoStore.create({
      mongoUrl: process.env.MONGO_URL,
      collection: "sessions",
      ttl: 1 * 24 * 60 * 60, //this is One day
    }),
    secret: process.env.MONGO_SESSION_SECRET,
    resave: false,
    saveUninitialized: true,
    cookie: {
      expires: 60 * 60 * 1000, //one hour
      secure: false,
      httpOnly: false,
      // maxAge: 3600000, //one hour
      sameSite: "none",
    },
    name: "scm",
    //5000 === 5sec
  })
);
app.set("trust proxy", 1);
app.use(function (req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header(
    "Access-Control-Allow-Headers",
    "Origin, X-Requested-With, Content-Type, Accept, authorization, Set-Cookie"
  );

  res.header("Access-Control-Allow-Methods", "GET,POST,DELETE,PUT,OPTIONS");
  next();
});
...
app.use(
  cors({
    origin: true,
    //  [
    //   "http://localhost:5000",
    //   "http://192.168.80.64:3000",
    //   "http://localhost:3000",
    // ],
    proxy: true,
    credentials: true,
    methods: ["HEAD", "POST", "PUT", "GET", "PATCH", "DELETE"],
  })
);
...
app.get("/", function (req, res) {
  res.sendFile(__dirname + "/build/index.html");
});

it works fine with npm run start on reactjs. it just does not work with build files. Thank you in advance



Solution 1:[1]

React application will serve through the entry build/index.html. This file has to be picked up by the back end server to serve the front end application: import the path module and add

app.use(express.static(path.resolve(__dirname, "./build")));
app.get("/", (req, res) => {
  res.sendFile(path.resolve(__dirname, "./build", "index.html"));
});

See Refrece.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Mukesh Maurya