我有一個快速服務器后端,我在其中使用會話來跟蹤用戶何時登錄或未登錄,并使用 passportJS 進行身份驗證。前端的 ReactJS。React 在默認埠 3000 上運行,而 express 應用程式在 5500 上運行。
現在,每當我對 /api/login 使用發布請求時,它都會登錄用戶并發送 200 ok 并使用護照用戶物件創建會話,然后重定向到個人資料頁面,我有另一個 GET 請求請求獲取用戶資料. 組態檔頁面向 /api/profile 發送一個 GET 請求,該請求檢查用戶是否經過身份驗證,如果是,則發回用戶資料以使用用戶詳細資訊填充組態檔頁面。但是現在,每次組態檔頁面向服務器發送 GET 請求時,它都會創建一個新會話,覆寫在 /api/login 中創建的會話,并丟失用戶資料,顯示用戶未經過身份驗證。
這是我的 server.js 檔案
const express = require("express");
const MongoStore = require("connect-mongo");
const indexRouter = require("./routes/index");
const app = express();
const cors = require("cors");
const bodyparser = require("body-parser");
const mongoose = require("mongoose");
const dotenv = require("dotenv");
const passport = require("./Authentication/passportConfig");
const session = require("express-session");
const cookieParser = require("cookie-parser");
dotenv.config({ path: "../app/Private/.env" });
let port = process.env.PORT;
app.use(bodyparser.json());
app.use(bodyparser.urlencoded({ extended: true }));
app.use(
cors({
origin: "http://localhost:3000",
methods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
credentials: true,
})
);
app.use(cookieParser("secret"));
app.use(
session({
secret: "secret",
store: MongoStore.create({ mongoUrl: process.env.ADMIN_URI }),
resave: false,
saveUninitialized: false,
cookie: { maxAge: 30 * 24 * 60 * 60 * 1000, httpOnly: true },
})
);
app.use(passport.initialize());
app.use(passport.session());
//Database connection process
mongoose
.connect(process.env.ADMIN_URI, {
useNewUrlParser: true,
useUnifiedTopology: true,
})
.then(() => console.log("connected to database"))
.catch(console.error);
//Route creation
app.use("/api", indexRouter);
app.listen(port, () => console.log("Server connected and running: " port));
這是我的 indexRouter 中的兩條路線
const express = require("express");
const router = express.Router();
const passport = require("../Authentication/passportConfig");
const dotenv = require("dotenv");
dotenv.config({ path: "../app/Private/.env" });
const nodemailer = require("nodemailer");
const User = require("../model/user");
const hash = require("../Authentication/passwordHash");
const validator = require("node-email-validation");
const Appointment = require("../model/appointment");
router.post("/login", passport.authenticate("local"), (req, res) => {
var time = new Date(Date.now());
console.log(
"Session ID before @ /login route: "
time.toLocaleTimeString()
": "
req.sessionID
);
if (req.user) {
console.log("Session ID after @ /login route: " req.sessionID);
console.log("User is logged in: " req.user.username);
console.log("User is Authenticated: " req.isAuthenticated());
res.status(200).json({ message: "Login successful" });
} else {
res.send(400).json({ message: "User not found" });
}
});
router.get("/profile", function (req, res) {
var time = new Date(Date.now());
console.log(
"Session ID @ /profile route: "
time.toLocaleTimeString()
": "
req.sessionID
);
if (req.isAuthenticated()) {
console.log(req.isAuthenticated());
console.log("user: " req.user.username);
return res.status(200).json(req.user);
num = num 1;
} else {
console.log("else Statement");
return res.status(302).json({ message: "User not found" });
}
});
這是來自不同路由的控制臺日志記錄會話的輸出
Session ID before @ /login route: 5:41:07 PM: 8Z1RebDKynOESWoQ5ecA3EecOojmthL9
Session ID after @ /login route: 8Z1RebDKynOESWoQ5ecA3EecOojmthL9
User is logged in: alex@s3v.us
User is Authenticated: true
Session ID @ /profile route: 5:41:09 PM: -peiT761fG_ZY9gLgWFpqeUE6hTZmRQV
else Statement
Session ID @ /profile route: 5:41:09 PM: kgXFngZMamCqh4mapynMQQN7cgL9Er-1
else Statement
Session ID @ /profile route: 5:41:09 PM: zCZTtlsK-g0MSvo9j5ZbAAs35vaXtsnO
else Statement
Session ID @ /profile route: 5:41:09 PM: Oq8J-s08m66P5JuuTO1RI5ZIy8oOeXRD
else Statement
這是登錄頁面中的 ReactJS 前端呼叫
const config = {
headers: {
"Access-Control-Allow-Origin": "http://localhost:3000",
"Access-Control-Allow-Methods": "GET,PUT,POST,DELETE,PATCH,OPTIONS",
"Access-Control-Allow-Credentials": "true",
},
};
const isLoggedIn = () => {
axios
.get("http://localhost:5500/api/profile", config)
.then((res) => {
console.log("Is user logged in status: " res.status);
console.log(res.data);
if (res.status === 200) {
window.location.href = "/MyProfile";
}
})
.catch((err) => {
console.log("err" err);
});
};
/*
on Submit function for the login page
*/
const onSubmitLogIn = (e) => {
e.preventDefault();
const user = {
username: username.toString().toLowerCase(),
password: password,
};
axios
.post("http://localhost:5500/api/login", user, config)
.then((res) => {
console.log(res.data);
if (res.status === 200) {
setSuccessMessage(true);
setTimeout(() => {
window.location.href = "/MyProfile";
}, 2000);
}
})
.catch((err) => {
setErrormessage(true);
});
};
這是 profile.jsx 中的鉤子呼叫和獲取請求
useEffect(() => {
fetchUserData();
}, []);
const fetchUserData = () => {
axios
.get("http://localhost:5500/api/profile", config)
.then((res) => {
console.log("res: " res);
console.log("User: " res.data);
setUserData(res.data);
})
.catch((err) => {
console.log(err);
console.log(err.response);
});
};
我不明白我哪里出錯了,為什么組態檔中的呼叫會創建一個新會話。
uj5u.com熱心網友回復:
將{withCredentials: true}選項添加到您的 Axios 呼叫中,以便 Axios 隨您的請求發送 cookie(以及會話 cookie)。
const fetchUserData = () => {
axios
.get("http://localhost:5500/api/profile", {withCredentials: true})
.then((res) => {
console.log("res: " res);
console.log("User: " res.data);
setUserData(res.data);
})
.catch((err) => {
console.log(err);
console.log(err.response);
});
};
當 cookie 未隨請求一起發送時,您的會話 cookie 不存在,并且后端每次都會創建一個新會話。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/531338.html
