我目前正在 React/Express 中創建一個應用程式,并且正在學習如何創建會話。我正在使用 express-session,因為這是每個人都推薦的,但我有意想不到的行為。
在我的路由帖子中,連接期間使用的路由,我嘗試為用戶創建一個新會話,但它似乎不起作用(沒有 cookie 并且未創建會話),而我的 console.log 回傳預期的資訊。
router.post('/login', async (req, res) => {
const user = await Users.findOne({where: {Email: req.body.Email}})
if (!user) res.json({error: "User doesn't exist"})
bcrypt.compare(req.body.Password, user.Password).then((match) => {
if (!match) res.json({error: "Wrong password"})
req.session.user = user.dataValues
console.log(req.session)
})
})
在每次重繪 頁面時呼叫的 get 路由中,我意識到會話是空的,并且創建了一個新的 cookie(我真的不知道為什么)。
router.get('/login', async (req, res) => {
console.log(req.session)
if (req.session.user) {
res.send({loggedIn: true, user: req.session.user})
} else {
res.send({ loggedIn: false})
}
})
這是我設定 express-session 和 cors 的方式(我讀到問題可能來自那里,但一切似乎都是正確的)。
app.use(cors({
origin: ["http://localhost:3000"],
methods: ["GET", "POST"],
credentials: true //permet d'activer les cookies
}))
app.use(session({
key: "userId",
secret: "foo",
resave: false,
saveUninitialised: true,
cookie: {
expires: 60 * 60 * 24
},
}))
我還讀到問題可能來自 API 呼叫,我使用 Axios 并且小心地Axios.defaults.withCredentials = true在呼叫之前添加了該行。
uj5u.com熱心網友回復:
您的router.post("/login", ...)路線永遠不會向客戶端發送任何回應。快速會話通過與瀏覽器建立 cookie 來作業,瀏覽器將在未來的請求中發回該 cookie。該 cookie 包含一個加密的會話密鑰,它是使會話成為可能的魔法醬。當您不從/loginPOST 發回任何回應時,該 cookie 永遠不會回傳到瀏覽器,因此會話 cookie 無法在未來的請求中發送回,因此會話不起作用。
相反,來自瀏覽器的下一個請求將沒有會話 cookie,因此 Express 將嘗試創建另一個新的空會話。
要解決這部分問題,請從您的 POST 請求中發回回應:
router.post('/login', async (req, res) => {
const user = await Users.findOne({where: {Email: req.body.Email}})
if (!user) res.json({error: "User doesn't exist"})
bcrypt.compare(req.body.Password, user.Password).then((match) => {
if (!match) res.json({error: "Wrong password"})
req.session.user = user.dataValues;
console.log(req.session)
res.send("some response"); // <== send some response here
}).catch(err => {
// some error handling here
console.log(err);
res.sendStatus(500);
});
});
對于使用 http 狀態來反映實際錯誤的更完整和集中的錯誤處理,您可以執行以下操作:
class myError extends Error {
constructor(message, status) {
super(message);
this.status = status;
}
}
router.post('/login', async (req, res) => {
try {
const user = await Users.findOne({where: {Email: req.body.Email}})
if (!user) throw new MyError("User doesn't exist", 404) ;
const match = await bcrypt.compare(req.body.Password, user.Password);
if (!match) throw new MyError("Wrong password", 401);
req.session.user = user.dataValues;
console.log(req.session);
res.json({loggedIn: true});
} catch(e) {
const status = e.status || 500;
res.status(status).json({error: e.message});
}
});
請注意,我已經停止await與.then()不被認為是好的風格混合,然后使用try/catch并將throw更全面的錯誤處理集成到一個地方。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/518049.html
