簡體   English   中英

HttpOnly Cookies 在 Web 檢查器中找不到

[英]HttpOnly Cookies not found in Web Inspector

我正在為使用 MERN 堆棧構建的網站進行用戶身份驗證,我決定使用存儲為 HttpOnly cookies 的 JWT 令牌。 The cookie was sent in a "Set-Cookie" field in response header when I used Postman to make the request but not in the Safari Web Inspector as shown in the image below. 在存儲選項卡中也沒有找到 cookies。

在此處輸入圖像描述

為了調試,我已將我的 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;

我在后端使用 express,這是我的 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 boolean並返回給客戶端。 我能夠在前端檢索此值,因此我認為這不是 CORS 錯誤。 此外,沒有引發任何錯誤,並且我的 web 頁面上不涉及 cookies 的所有其他 API 請求也可以正常工作。

Another interesting thing is that despite using the same data (A JS object containing {username:"Joshua", password:"qwerty"}) for both Postman and the React code, validCredentials evaluates to true in Postman and false in the Web Inspector. 這是我數據庫中的現有文檔,我希望返回的值是 true,在我添加 cookies 之前就是這種情況

我可以知道我做錯了什么,或者你對我如何解決這個問題有什么建議嗎? 我是網絡開發的初學者

編輯

通過戴夫的回答,我可以在前端收到“Set-Cookie”header。 但是由於某種原因,它沒有出現在 web 檢查器的存儲選項卡中。

這是響應 header

在此處輸入圖像描述

這是來自站點的 cookies 通常出現的存儲選項卡

在此處輸入圖像描述

如果您嘗試將請求作為 json 發送,則需要設置內容類型 header 和JSON.stringify為 Z496A8CFFDE69311CBD

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 設置在另一個塊中。

您看不到它,因為您已將其設為 httpOnly cookie。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM