Express-session 未在浏览器中设置 cookie

Express-session is not setting cookies in browser

所以我使用 express-session 包来设置 cookie 和会话。它还连接到我的 MongoDB 商店以存储会话。当用户登录时,会话会很好地存储在数据库中,但是浏览器中没有 cookie。我的应用程序在 http://localhost:8080/ 中是 运行,我的服务器在 http://localhost:5500/ 中是 运行。

index.js:

const express = require('express');
const app = express();
const bodyParser = require('body-parser');
const expressSession = require('express-session');
const mStore = require('./model/database.js').Mstore;
const routes = require('./control/router.js');
const mongooseConnect = require('./model/database.js').mongooseConnect;


app.use(
   expressSession({ 
      secret: 'my secret', 
      resave: false, 
      saveUninitialized: false,
      store: mStore
   }),
   bodyParser.urlencoded({ extended: true }),
   bodyParser.json(),
   routes
);


mongooseConnect(() => app.listen(process.env.PORT || 5500));

router.js:

const express = require('express');
const router = express.Router();
const notesModel = require('../model/database.js').notesModel;
const userModel = require('../model/database.js').userModel;
const cors = require('cors');

router.options('/login', cors());

router.post('/login', cors(), (req, res) => {
   userModel.findOne({ admin_username: req.body.username, admin_password: req.body.password }, (err, data) => {
      if (err) return console.log(err);
      
      if (data) {
         req.session.isLoggedIn = true; // Saves in database just fine.
         res.status(200).json('Login Success'); // This line works just fine as well.
      } else {
         console.log(req.session.isLoggedIn);
         res.status(401).json('Login Failed: Incorrect ID or Password.');
      }
   });
});

浏览器:

所以在我给出答案之前我会说 JWT 不是处理会话的安全方式

如何处理Express-session

首先你需要以下软件包

npm i express-session connect-mongodb-session 或 yarn add express-session connect-mongodb-session

现在我们有了安装 mongoStore 和 express-session 中间件所需的包:

//Code in server.js/index.js (Depending on your server entry point)
import expressSession from "express-session";
import MongoDBStore from "connect-mongodb-session";
import cors from "cors";
const mongoStore = MongoDBStore(expressSession);

const store = new mongoStore({
  collection: "userSessions",
  uri: process.env.mongoURI,
  expires: 1000,
});
app.use(
  expressSession({
    name: "SESS_NAME",
    secret: "SESS_SECRET",
    store: store,
    saveUninitialized: false,
    resave: false,
    cookie: {
      sameSite: false,
      secure: process.env.NODE_ENV === "production",
      maxAge: 1000,
      httpOnly: true,
    },
  })
);

现在会话中间件已准备就绪,但现在您必须设置 cors 以接受您的 ReactApp,以便传递 cookie 并由服务器将其设置在那里

//Still you index.js/server.js (Server entry point)

app.use(
  cors({
    origin: "http://localhost:3000",
    methods: ["POST", "PUT", "GET", "OPTIONS", "HEAD"],
    credentials: true,
  })
);

现在我们的中间件都设置好了,让我们看看你的登录路径

router.post('/api/login', (req, res)=>{
    //Do all your logic and now below is how you would send down the cooki

    //Note that "user" is the retrieved user when you were validating in logic
    // So now you want to add user info to cookie so to validate in future
    const sessionUser = {
       id: user._id,
       username: user.username,
       email: user.email,
    };
    //Saving the info req session and this will automatically save in your     mongoDB as configured up in sever.js(Server entry point)
    request.session.user = sessionUser;

    //Now we send down the session cookie to client
    response.send(request.session.sessionID);

})

现在我们的服务器已准备就绪,但现在我们必须修复我们在客户端中发出请求的方式,以便此流程可以 100% 工作:

下面的代码:React 应用程序/任何 fron-tend 你在处理登录的地方使用

//So you will have all your form logic and validation and below
//You will have a function that will send request to server 

const login = () => {
    const data = new FormData();
    data.append("username", username);
    data.append("password", password);

    axios.post("http://localhost:5000/api/user-login", data, {
      withCredentials: true, // Now this is was the missing piece in the client side 
    });
};

有了这一切,您现在的服务器会话 cookie 为 httpOnly