My authentication cookies are disappear when I refresh my page created in react and express.js when I deploy it to production in RAILWAY

74 views Asked by At

I have this middleware funtcions cookies created in express using jwt :

export const createAccessToken = async (payload) => {
  return new Promise((resolve, reject) => {
    jwt.sign(payload, TOKEN_SECRET, { expiresIn: "1d" }, (err, token) => {
      if (err) reject(err);
      resolve(token);
    });
  });
};

and this response when I login, httpOnly is commited because is not working me in localhost and production

const token = await createAccessToken({
      id: userFound._id,
    });

    res
      .cookie("access_token", token, {
        //httpOnly: true,
        secure: true,
        sameSite: "None",
        domain: DOMAIN,
      })
      .status(200)

Also I am using Express and using CORS, app.use( cors({ credentials: true, origin: [FRONTEND_URL], }) );, I dont have any problem with CORS. In react I am using useContext and axios to authentincation: I declared withCredencials TRUE,

import axios from "axios";
import { API_URL } from "../config";

const instance = axios.create({
  baseURL: API_URL,
  withCredentials: true,
});

export default instance;
import { useEffect } from "react";
import { createContext, useContext, useState } from "react";
import {
  loginRequest,
  registerRequest,
  verifyTokenRequest,
  logoutRequest,
  verifyEmailRequest,
  verifyEmailTokenRequest,
} from "../api/auth";
import Cookies from "js-cookie";

const AuthContext = createContext();

export const useAuth = () => {
  const context = useContext(AuthContext);
  if (!context) throw new Error("useAuth must be used within a AuthProvider");
  return context;
};

export const AuthProvider = ({ children }) => {
  const [user, setUser] = useState({});
  const [isAuthenticated, setIsAuthenticated] = useState(false);
  const [errors, setErrors] = useState([]);
  const [loading, setLoading] = useState(true);

  // clear errors after 5 seconds
  useEffect(() => {
    if (errors.length > 0) {
      const timer = setTimeout(() => {
        setErrors([]);
      }, 5000);
      return () => clearTimeout(timer);
    }
  }, [errors]);

  const signup = async (user) => {
    try {
      const res = await registerRequest(user);
      if (res.status === 200) {
        setUser(res.data);
        setIsAuthenticated(true);
      }
    } catch (error) {
      console.log(error);
      setErrors(error.response.data.message);
    }
  };

  const signin = async (user) => {
    try {
      const res = await loginRequest(user);
      setUser(res.data);
      setIsAuthenticated(true);
    } catch (error) {
      console.log(error);
      setErrors(error.response.data.message);
    }
  };

  const verifyEmail = async (data) => {
    try {
      const res = await verifyEmailRequest(data);
      return res.data;
    } catch (error) {
      console.log(error);
      setErrors(error.response.data.message);
    }
  };

  const verifyEmailToken = async (data) => {
    try {
      const res = await verifyEmailTokenRequest(data);
      return res.data;
    } catch (error) {
      console.log(error);
      setErrors(error.response.data.message);
    }
  };

  const logout = async () => {
    Cookies.remove("access_token");
    setUser(null);
    setIsAuthenticated(false);
  };

  useEffect(() => {
    const checkLogin = async () => {
      const token = Cookies.get("access_token");
      if (!token) {
        setIsAuthenticated(false);
        setLoading(false);
        return;
      }

      try {
        const res = await verifyTokenRequest(token);
        if (!res.data) return setIsAuthenticated(false);
        setIsAuthenticated(true);
        setUser(res.data);
        setLoading(false);
      } catch (error) {
        setIsAuthenticated(false);
        setLoading(false);
      }
    };
    checkLogin();
  }, []);

  return (
    <AuthContext.Provider
      value={{
        user,
        signup,
        signin,
        verifyEmail,
        verifyEmailToken,
        logout,
        isAuthenticated,
        errors,
        loading,
      }}
    >
      {children}
    </AuthContext.Provider>
  );
};

export default AuthContext;
``` in my localhost when I refresh my page is working and when I deploy in Railway and i refresh the deployed page when I was loged, the cookies was deleted and and my login is not maintaining the same as on my localhost. 
PD. 

httpOnly: true, secure: true, sameSite: "None",

I try to do this and is not working, help me please


I hope the cookies remain in production when I refresh my page.
1

There are 1 answers

1
Abdullah Bin Rashid On

You can create persistent cookies. They won't be deleted when the browser is closed. Just set the expires value when sending the cookie.

const token = await createAccessToken({
      id: userFound._id,
    });

    res
      .cookie("access_token", token, {
        //httpOnly: true,
        secure: true,
        sameSite: "None",
        domain: DOMAIN,
        expires: TIME // Expiry date of the cookie in GMT. If not specified or set to 0, creates a session cookie.
      })
      .status(200)

Read this for more info:

https://www.w3schools.com/js/js_cookies.asp

https://expressjs.com/en/5x/api.html#res.cookie