выборка: файлы cookie не получают файлы cookie

#node.js #cookies #fetch #cross-domain

#node.js #файлы cookie #выборка #междоменный

Вопрос:

У меня есть экспресс-сервер, работающий на локальном хосте: 5000, и клиент, работающий на порту 3000. После отправки post-запроса от клиента для входа в систему с использованием fetch API браузер не устанавливает cookie. Я получаю cookie в заголовке ответа как «set-cookie», но он не установлен в браузере на стороне клиента.

Вот мой код запроса на выборку:

 return (
    fetch(baseUrl   "users/login", {
      method: "POST",
      body: JSON.stringify(User),
      headers: {
        "Content-Type": "application/json",
      },
      credentials: "same-origin",
    })
 

Код на стороне сервера:

 router
  .route("/login")
  .options(cors.corsWithOptions, (req, res) => {
    res.sendStatus(200);
  })
  .post(cors.corsWithOptions, (req, res, next) => {
    passport.authenticate("local", (err, user, info) => {
      if (err) return next(err);

      if (!user) {
        res.statusCode = 401;
        res.setHeader("Content-Type", "application/json");
        res.json({ success: false, status: "Log In unsuccessful", err: info });
      }
      req.logIn(user, (err) => {
        if (err) {
          res.statusCode = 401;
          res.setHeader("Content-Type", "application/json");
          // res.header("Access-Control-Allow-Credentials", true);
          res.json({
            success: false,
            status: "Login Unsuccessful!",
            err: "Could not log in user!",
          });
        }

        var token = authenticate.getToken({ _id: req.user._id });
        res.cookie("jwt-token", token, {
          signed: true,
          path: "/",
          httpOnly: true,
          
        });
        res.statusCode = 200;
        res.setHeader("Content-Type", "application/json");

        res.json({ success: true, status: "Login Successful!", token: token });
      });
    })(req, res, next);
  });
  
 

Комментарии:

1. Не отправляйте изображения своего кода, если вам нужна помощь в Stack Overflow скорее всего, вы получите помощь, если скопируете и вставите код с вашим вопросом, не забыв его форматировать… Пожалуйста, исправьте свой вопрос

2. Я изменил его. Пожалуйста, помогите сейчас

3. О, хорошо, я вижу, что здесь вы пытаетесь использовать файлы cookie сеанса на стороне сервера, я дам решение этой проблемы, я дам реализацию express-session amp; MongoDB … Но из вашего кода я вижу, что вы отправляете много данных полезной нагрузки, но вы должны просто отправлять токен только также в настройках cors вам нужны некоторые настройки конфигурации, которые вы увидите в моем ответе

Ответ №1:

Как обрабатывать сеанс на стороне сервера с помощью Express-session

Во-первых, вам понадобятся следующие пакеты

npm i express-session connect-mongodb-session или yarn добавить экспресс-подключение к сеансу-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 / независимо от того, что вы используете, где вы выполняете вход в систему

 //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

Комментарии:

1. Это настолько подробно, насколько это возможно для реализации сеанса на стороне сервера надеюсь, что ответ поможет вам в ваших проектах и будущих проектах