Файлы cookie HttpOnly не найдены в веб-инспекторе

Я работаю над аутентификацией пользователей для веб-сайта, созданного с использованием стека MERN, и я решил использовать токены JWT, хранящиеся в виде файлов cookie HttpOnly. Файл cookie был отправлен в поле Set-Cookie в заголовке ответа, когда я использовал Postman для выполнения запроса, но не в веб-инспекторе Safari, как показано на изображении ниже. На вкладке «Хранилище» также не найдены файлы cookie.

введите здесь описание изображения

Я упростил свою форму входа в React до кнопки, которая отправляет имя пользователя и пароль пользователя для отладки.

import React from "react";

const sendRequest = async (event) => {
  event.preventDefault();
  let response;

  try {
    response = await fetch("http://localhost:5000/api/user/login", {
      method: "POST",
      body: { username: "Joshua", password: "qwerty" },
      mode: "cors",
      // include cookies/ authorization headers
      credentials: "include",
    });
  } catch (err) {
    console.log(err);
  }
  if (response) {
    const responseData = await response.json();
    console.log(responseData);
  }
};

const test = () => {
  return (
    <div>
      <input type="button" onClick={sendRequest} value="send" />
    </div>
  );
};

export default test;

Я использую экспресс на бэкэнде, и это мой index.js, где сначала принимаются все входящие запросы.

const app = express();

app.use(bodyParser.json());

app.use("/images", express.static("images"));
app.use((req, res, next) => {
  res.set({
    "Access-Control-Allow-Origin": req.headers.origin,
    "Access-Control-Allow-Credentials": "true",
    "Access-Control-Allow-Headers": "Content-Type, *",
    "Access-Control-Allow-Methods": "GET, POST, PATCH, DELETE",
  });

  next();
});

app.use(cookieParser());

// api requests for user info/ login/signup
app.use("/api/user", userRoutes);

Это промежуточное программное обеспечение, на которое в конечном итоге направляется запрос на вход.

const login = async (req, res, next) => {
  const { username, password } = req.body;
  let existingUser;
  let validCredentials;
  let userID;
  let accessToken;

  try {
    existingUser = await User.findOne({ username });
  } catch (err) {
    return next(new DatabaseError(err.message));
  }

  // if user cannot be found -> username is wrong
  if (!existingUser) {
    validCredentials = false;
  } else {
    let isValidPassword = false;
    try {
      isValidPassword = await bcrypt.compare(password, existingUser.password);
    } catch (err) {
      return next(new DatabaseError(err.message));
    }

    // if password is wrong
    if (!isValidPassword) {
      validCredentials = false;
    } else {
      try {
        await existingUser.save();
      } catch (err) {
        return next(new DatabaseError(err.message));
      }

      userID = existingUser.id;
      validCredentials = true;

      accessToken = jwt.sign({ userID }, SECRET_JWT_HASH);
      res.cookie("access_token", accessToken, {
        maxAge: 3600,
        httpOnly: true,
      });
    }
  }

  res.json({ validCredentials });
};

Дополнительная информация

В промежуточном программном обеспечении для входа в систему устанавливается логическое значение validCredentials, которое возвращается клиенту. Мне удалось получить это значение во внешнем интерфейсе, поэтому я не думаю, что это ошибка CORS. Кроме того, никаких ошибок не возникало, и все другие запросы API на моей веб-странице, которые не используют файлы cookie, также работают нормально.

Еще одна интересная вещь заключается в том, что, несмотря на использование одних и тех же данных (объект JS, содержащий {username:Joshua, password:qwerty}) как для Postman, так и для кода React, validCredentials оценивается как true в Postman и как false в веб-инспекторе. Это существующий документ в моей базе данных, и я ожидаю, что возвращаемое значение будет истинным, как это было до того, как я добавил файлы cookie.

Могу ли я узнать, что я сделал неправильно, или у вас есть какие-либо предложения о том, как я могу решить эту проблему? Я новичок в веб-разработке

ИЗМЕНИТЬ

С ответом Дейва я могу получить заголовок Set-Cookie во внешнем интерфейсе. Однако по какой-то причине он не отображается на вкладке «Хранилище» в веб-инспекторе.

Это заголовок ответа

введите здесь описание изображения

Это вкладка «Хранилище», где обычно появляются файлы cookie с сайта.

введите здесь описание изображения


person Richard Ding    schedule 16.08.2020    source источник


Ответы (1)


Если вы пытаетесь отправить запрос как json, вам нужно установить заголовок типа контента и JSON.stringify объект:

response = await fetch("http://localhost:5000/api/user/login", {
  method: "POST",
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ username: "Joshua", password: "qwerty" }),
  mode: "cors",
  // include cookies/ authorization headers
  credentials: "include",
});

Прямо сейчас вы, вероятно, получаете эквивалент

existingUser = User.findOne({ username: undefined})

и поэтому, когда вы делаете:

if (!existingUser) {
    validCredentials = false;
} else { /* ... */ }

вы получаете блок validCredentials = false, а cookie устанавливается в другом блоке.

person dave    schedule 16.08.2020
comment
О, это было в точку! Теперь заголовок Set-Cookie появляется в заголовке моего ответа, но сам файл cookie не отображается на вкладке «Хранилище» в веб-инспекторе. У вас есть идеи, в чем может быть проблема? - person Richard Ding; 16.08.2020
comment
недостаточно информации, чтобы продолжить для этого. файл cookie по-прежнему отправляется при последующих запросах и просто не отображается на вкладке, или файл cookie на самом деле не устанавливается? - person dave; 16.08.2020
comment
Да, файл cookie отправляется каждый раз, и validCredentials оценивается как true. Как отличить файл cookie, который не отображается и не устанавливается? - person Richard Ding; 16.08.2020
comment
Если вы делаете другой запрос, и он отправляет файл cookie в запросе, тогда он установлен. Я не знаю, почему это не отображается в инструментах разработчика, возможно, вы просто ищете не в том месте. - person dave; 16.08.2020
comment
Похоже, что файлы cookie работают нормально, просто они не отображаются в инструментах разработчика. Спасибо за помощь - person Richard Ding; 16.08.2020