Reactjs 客户端不从 Express 服务器获取 cookie
Reactjs client does not get cookie from Express server
我的设置如下:
http://localhost:3000
中的 Reactjs 客户端
- 快递服务器在
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");
});
我的场景是
- 客户端单击登录按钮向 api
/login
发出 post 请求
- 服务器收到请求,生成jwt并放入httpOnly cookie然后响应客户端
- 客户端单击 Ping 按钮向 api
/ping
发出 post 请求(包含上述 cookie)
- 服务器从请求中接收并验证 cookie 中的 jwt
我可以在第 2 步看到从服务器发回的 cookie(使用 Chrome 开发工具):
token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiVE9LRU4iLCJpYXQiOjE2NDg1NDM0MTgsImV4cCI6MTY0ODYyOTgxOH0._PiVonFtdyCo3O-1Xwupd2zxlE-J8DWa9OONVeP4e_s; Path=/; HttpOnly
但是我在第 3 步的请求中没有看到它,然后在第 4 步我尝试打印 req.cookies
时得到 [Object: null prototype] {}
我该如何解决这个问题?
谢谢!
对于像我这样面临这个问题的人。所有行都有 // 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");
});
我的设置如下:
http://localhost:3000
中的 Reactjs 客户端
- 快递服务器在
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");
});
我的场景是
- 客户端单击登录按钮向 api
/login
发出 post 请求
- 服务器收到请求,生成jwt并放入httpOnly cookie然后响应客户端
- 客户端单击 Ping 按钮向 api
/ping
发出 post 请求(包含上述 cookie)
- 服务器从请求中接收并验证 cookie 中的 jwt
我可以在第 2 步看到从服务器发回的 cookie(使用 Chrome 开发工具):
token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiVE9LRU4iLCJpYXQiOjE2NDg1NDM0MTgsImV4cCI6MTY0ODYyOTgxOH0._PiVonFtdyCo3O-1Xwupd2zxlE-J8DWa9OONVeP4e_s; Path=/; HttpOnly
但是我在第 3 步的请求中没有看到它,然后在第 4 步我尝试打印 req.cookies
[Object: null prototype] {}
我该如何解决这个问题?
谢谢!
对于像我这样面临这个问题的人。所有行都有 // 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");
});