expresscookiesexpress-session

I have a problem with storing cookies in Express


const app = express();
app.use(
  cors({
    origin: "http://localhost:3005",
    credentials: true,
  })
);
app.use(cookieParser());
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(
  session({
    secret: "TAMARA",
    resave: true,
    saveUninitialized: true,
    cookie: { secure: false },
  })
);

const users = {};

app.use(passport.initialize());
app.use(passport.session());

passport.serializeUser((user, done) => {
  users[user.id] = user;
  session.user_id = user.id;
  done(null, user.id);
});

passport.deserializeUser((id, done) => {
  console.log("deserialize", id);
  const user = users[id];
  done(null, user);
});

passport.use(
  new GitHubStrategy(
    {
      clientID: id,
      clientSecret: secret,
      callbackURL: "http://127.0.0.1:3000/auth/github/callback",
    },
    function (accessToken, refreshToken, profile, cb) {
      users[profile.id] = profile;
      return cb(null, profile);
    }
  )
);

const http = require("http").createServer(app);

app.route("/auth/github").get(passport.authenticate("github"));

app.route("/auth/github/callback").get(passport.authenticate("github", { failureRedirect: "/" }), (req, res) => {
  console.log("req user id", req.user.id);
  req.session.user = req.user;
  req.session.user_id = req.user.id;
  res.redirect("http://localhost:3005");
});

function ensureAuthenticated(req, res, next) {
  console.log("ensureAuthenticated", req.isAuthenticated(), "session", req.session);
  if (req.isAuthenticated()) {
    return next();
  } else {
    res.status(401).json({ message: "Unauthorized" });
  }
}

app.route("/test").get(ensureAuthenticated, (req, res) => {
  res.json({ message: "Hello world" });
});

http.listen(3000, () => {
  console.log("Listening on port " + 3000);
});  

On the frontend, requests have a very simple form

<div>
    <a href="/auth/github">Github</a>
</div>

 <button
        onClick={() => {
          fetch("/api/test", {
            method: "GET",
            credentials: "include",
          })
            .then((res) => {
              return res.json();
            })
            .then((data) => {
              console.log(data);
            });
        }}
      >
        Click
</button> 
// The way I set up a proxy  
export default defineConfig({
  plugins: [react()],

  server: {
    port: 3005,
    proxy: {
      "/api": {
        target: "http://localhost:3000",
        changeOrigin: true,
        rewrite: (path) => path.replace(/^\/api/, ""),
      },
      "/auth": {
        target: "http://localhost:3000",
        changeOrigin: true,
      },
    },
  },
});

In short, express-session seems not to be storing data. I've tried various options within the middleware, but it's not working. In a bit more detail: logging in via GitHub is successful, I attach that data to req.session, express-session generates a cookie that finds its way to the browser (console.log("cookie", req.cookies) prints cookie after request; I've learned that the cookie is not stored in the browser immediately after logging in but after requesting a protected route). However, with the next request, I encounter issues, and I don't have req.user or req.isAuthenticated(). Can anyone see what the frustrating problem might be?


Solution

  • The problem was that instead of using http://localhost:3000 in the GitHub settings, I used 127.0.01. When I replaced 127.0.01 with localhost in GitHub and the code, everything started working.