简体   繁体   English

HttpOnly Cookies 在 Web 检查器中找不到

[英]HttpOnly Cookies not found in Web Inspector

I am working on user authentication for a website built using the MERN stack and I have decided to use JWT tokens stored as HttpOnly cookies.我正在为使用 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. 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. There are no cookies found in the storage tab either.在存储选项卡中也没有找到 cookies。

在此处输入图像描述

I have simplified my React login form to a button that submits the username and password of the user for the sake of debugging为了调试,我已将我的 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;

I am using express on the backend and this is my index.js where all incoming requests are first received我在后端使用 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);

This is the middleware that the login request is eventually directed to这是登录请求最终定向到的中间件

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 });
};

Extra information额外的信息

In the login middleware, a validCredentials boolean is set and returned to the client.在登录中间件中,设置了一个validCredentials boolean并返回给客户端。 I was able to retrieve this value on the front end hence I do not think it is a CORS error.我能够在前端检索此值,因此我认为这不是 CORS 错误。 Furthermore, no errors were thrown and all other API requests on my web page that do not involve cookies work fine as well.此外,没有引发任何错误,并且我的 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. 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. It is an existing document in my database and I would expect the value returned to be true, which was the case before I added cookies这是我数据库中的现有文档,我希望返回的值是 true,在我添加 cookies 之前就是这种情况

May I know what I have done wrong or do you have any suggestions on how I can resolve this issue?我可以知道我做错了什么,或者你对我如何解决这个问题有什么建议吗? I am a beginner at web-development我是网络开发的初学者

EDIT编辑

With dave's answer I can receive the "Set-Cookie" header on the frontend.通过戴夫的回答,我可以在前端收到“Set-Cookie”header。 However it does not appear in the Storage tab in the web inspector for some reason.但是由于某种原因,它没有出现在 web 检查器的存储选项卡中。

This is the response header这是响应 header

在此处输入图像描述

This is the Storage tab where cookies from the site usually appears这是来自站点的 cookies 通常出现的存储选项卡

在此处输入图像描述

If you're trying to send the request as json, you need to set the content type header, and JSON.stringify the object:如果您尝试将请求作为 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",
});

Right now you're probably getting the equivalent of现在你可能得到相当于

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

and so when you do:所以当你这样做时:

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

you get the validCredentials = false block, and the cookie is set in the other block.你得到了validCredentials = false块,并且 cookie 设置在另一个块中。

You can not see it because you have made it httpOnly cookie.您看不到它,因为您已将其设为 httpOnly cookie。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM