Reactjs客户端无法从Express服务器获取cookie

发布于 2025-01-17 11:26:33 字数 2696 浏览 0 评论 0原文

我的设置如下:

  • Reactjs 客户端位于 http://localhost:3000
  • Express 服务器位于 http://localhost:5000

客户端:

import { useState } from "react";
import axios from "axios";

import "./App.css";

const API = axios.create({ baseURL: "http://localhost:5000" });

function App() {
  const [auth, setAuth] = useState(false);
  const login = () => API.post("/login").then((res) => setAuth(true));
  const ping = () =>
    API.post("/ping", { withCredentials: true }).then((res) =>
      console.log(res)
    );
  return (
    <div className="wrapper">
      <button className="log-btn btn" onClick={login}>
        Login
      </button>
      {auth && (
        <button className="ping-btn btn" onClick={ping}>
          Ping
        </button>
      )}
    </div>
  );
}

export default App;

服务器:

import express from "express";
import cors from "cors";
import cookieParser from "cookie-parser";
import jwt from "jsonwebtoken";

// express
const app = express();

// middlewares
app.use(express.json({ limit: "60mb" }));
app.use(cors());
app.use(cookieParser());
app.use(function (req, res, next) {
  console.log("VLL");
  res.header("Access-Control-Allow-Credentials", true);
  res.header("Access-Control-Allow-Origin", req.headers.origin);
  res.header("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE");
  res.header(
    "Access-Control-Allow-Headers",
    "X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept"
  );
  next();
});

// routes
app.post("/login", (req, res) => {
  const token = jwt.sign({ name: "TOKEN" }, "SECRET_KEY", {
    expiresIn: "24h",
  });
  res.cookie("token", token, {
    httpOnly: true,
    secure: false,
  });
  res.status(202).send("LOGGED IN");
});

app.post("/ping", (req, res) => {
  console.log(req.cookies);
  res.status("202").send("YOU GOT IT");
});

// run
app.listen(5000, () => {
  console.log("Server is running on http://localhost:5000");
});

我的场景是

  1. 客户端单击登录按钮向 api 发出 post 请求 /login
  2. 服务器收到请求,创建一个 jwt 并放入 httpOnly cookie,然后响应客户端
  3. 客户端单击 Ping 按钮向 api 发出 post 请求(包含上述 cookie) /ping
  4. 服务器接收并验证来自请求的 cookie 内的 jwt

我可以在步骤 2 中看到从服务器发回的 cookie(使用 Chrome 开发工具):

token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiVE9LRU4iLCJpYXQiOjE2NDg1NDM0MTgsImV4cCI6MTY0ODYyOTgxOH0._PiVonFtdyCo3O-1Xwupd2zxlE-J8DWa9OONVeP4e_s; Path=/; HttpOnly

但我在步骤 3 的请求中没有看到它然后在步骤 4 中,当尝试打印 req.cookies 时,我得到 [Object: null prototype] {}

我该如何解决这个问题?

谢谢你!

My set up as below:

  • Reactjs client in http://localhost:3000
  • Express server in http://localhost:5000

Client:

import { useState } from "react";
import axios from "axios";

import "./App.css";

const API = axios.create({ baseURL: "http://localhost:5000" });

function App() {
  const [auth, setAuth] = useState(false);
  const login = () => API.post("/login").then((res) => setAuth(true));
  const ping = () =>
    API.post("/ping", { withCredentials: true }).then((res) =>
      console.log(res)
    );
  return (
    <div className="wrapper">
      <button className="log-btn btn" onClick={login}>
        Login
      </button>
      {auth && (
        <button className="ping-btn btn" onClick={ping}>
          Ping
        </button>
      )}
    </div>
  );
}

export default App;

Server:

import express from "express";
import cors from "cors";
import cookieParser from "cookie-parser";
import jwt from "jsonwebtoken";

// express
const app = express();

// middlewares
app.use(express.json({ limit: "60mb" }));
app.use(cors());
app.use(cookieParser());
app.use(function (req, res, next) {
  console.log("VLL");
  res.header("Access-Control-Allow-Credentials", true);
  res.header("Access-Control-Allow-Origin", req.headers.origin);
  res.header("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE");
  res.header(
    "Access-Control-Allow-Headers",
    "X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept"
  );
  next();
});

// routes
app.post("/login", (req, res) => {
  const token = jwt.sign({ name: "TOKEN" }, "SECRET_KEY", {
    expiresIn: "24h",
  });
  res.cookie("token", token, {
    httpOnly: true,
    secure: false,
  });
  res.status(202).send("LOGGED IN");
});

app.post("/ping", (req, res) => {
  console.log(req.cookies);
  res.status("202").send("YOU GOT IT");
});

// run
app.listen(5000, () => {
  console.log("Server is running on http://localhost:5000");
});

My scenario is

  1. Client click Login button to make a post request to api /login
  2. Server receive the request, make a jwt and put in httpOnly cookie then response to client
  3. Client click Ping button to make a post request (contains above cookie) to api /ping
  4. Server receive and verify jwt inside cookie from request

I can see the cookie sent back from server at step 2 (using Chrome Dev Tools):

token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiVE9LRU4iLCJpYXQiOjE2NDg1NDM0MTgsImV4cCI6MTY0ODYyOTgxOH0._PiVonFtdyCo3O-1Xwupd2zxlE-J8DWa9OONVeP4e_s; Path=/; HttpOnly

But I don't see it in the request at step 3 then in step 4 I get [Object: null prototype] {} when try to print req.cookies

How I can fix this problem ?

Thank you!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

淡淡绿茶香 2025-01-24 11:26:33

对于像我这样面临这个问题的人。所有行都有 // NEW 注释解决此问题

客户端:

import { useState } from "react";
import axios from "axios";
import "./App.css";
axios.defaults.withCredentials = true; // NEW

const API = axios.create({ baseURL: "http://localhost:5000" });

function App() {
  const [auth, setAuth] = useState(false);
  const login = () => API.post("/login").then((res) => setAuth(true));
  const ping = () =>
    API.post("/ping", { withCredentials: true }).then((res) =>
      console.log(res)
    );
  return (
    <div className="wrapper">
      <button className="log-btn btn" onClick={login}>
        Login
      </button>
      {auth && (
        <button className="ping-btn btn" onClick={ping}>
          Ping
        </button>
      )}
    </div>
  );
}

export default App;

服务器:

import express from "express";
import cors from "cors";
import cookieParser from "cookie-parser";
import jwt from "jsonwebtoken";

// express
const app = express();

// middlewares
app.use(express.json({ limit: "60mb" }));
app.use(
  cors({
    origin: "http://localhost:3000", // NEW
    credentials: true, // NEW
  })
);
app.use(cookieParser());
app.use(function (req, res, next) {
  res.header("Access-Control-Allow-Credentials", true);
  res.header("Access-Control-Allow-Origin", req.headers.origin);
  res.header("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE");
  res.header(
    "Access-Control-Allow-Headers",
    "X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept"
  );
  next();
});

// routes
app.post("/login", (req, res) => {
  const token = jwt.sign({ name: "TOKEN" }, "SECRET_KEY", {
    expiresIn: "24h",
  });
  res.cookie("token", token, {
    httpOnly: true,
    secure: false,
  });
  res.status(202).send("LOGGED IN");
});

app.post("/ping", (req, res) => {
  console.log(req.cookies);
  res.status("202").send("YOU GOT IT");
});

// run
app.listen(5000, () => {
  console.log("Server is running on http://localhost:5000");
});

For someone who facing this problem like me. All lines have // NEW comment resolve this problem

Client:

import { useState } from "react";
import axios from "axios";
import "./App.css";
axios.defaults.withCredentials = true; // NEW

const API = axios.create({ baseURL: "http://localhost:5000" });

function App() {
  const [auth, setAuth] = useState(false);
  const login = () => API.post("/login").then((res) => setAuth(true));
  const ping = () =>
    API.post("/ping", { withCredentials: true }).then((res) =>
      console.log(res)
    );
  return (
    <div className="wrapper">
      <button className="log-btn btn" onClick={login}>
        Login
      </button>
      {auth && (
        <button className="ping-btn btn" onClick={ping}>
          Ping
        </button>
      )}
    </div>
  );
}

export default App;

Server:

import express from "express";
import cors from "cors";
import cookieParser from "cookie-parser";
import jwt from "jsonwebtoken";

// express
const app = express();

// middlewares
app.use(express.json({ limit: "60mb" }));
app.use(
  cors({
    origin: "http://localhost:3000", // NEW
    credentials: true, // NEW
  })
);
app.use(cookieParser());
app.use(function (req, res, next) {
  res.header("Access-Control-Allow-Credentials", true);
  res.header("Access-Control-Allow-Origin", req.headers.origin);
  res.header("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE");
  res.header(
    "Access-Control-Allow-Headers",
    "X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept"
  );
  next();
});

// routes
app.post("/login", (req, res) => {
  const token = jwt.sign({ name: "TOKEN" }, "SECRET_KEY", {
    expiresIn: "24h",
  });
  res.cookie("token", token, {
    httpOnly: true,
    secure: false,
  });
  res.status(202).send("LOGGED IN");
});

app.post("/ping", (req, res) => {
  console.log(req.cookies);
  res.status("202").send("YOU GOT IT");
});

// run
app.listen(5000, () => {
  console.log("Server is running on http://localhost:5000");
});
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文