我有一個函式可以創建JWT-tokens并將其設定為cookie。我在我的登錄控制器中使用這個函式,就在我向客戶端發送回應之前。問題是,控制器在set-JWT-as-cookies函式完成之前就發送了一個回應。
控制器
exports.login = catchAsync(async (req, res) => {
const { username, password } = req.body;
const user = await User.findOne({ username }).select(" password")。
if (!user || !(await bcrypt.compare(password, user.password))) {
return res.status(401).json("wrong_credentials")。
}
await jwtHelper.createTokens(user._id, res)。
console.log("right before sending a response", Date.now())。
res.status(200).json({
status: "成功"。
data: {
role: user.role,
},
});
});
createTokens函式
exports.createTokens = catchAsync(async (userId, res) => {
const accessToken = createAccessToken(userId);
const { tokenId: refreshTokenId, token: refreshToken } = createRefreshToken()。
await Token.create({ tokenId: refreshTokenId })。
const accessCookieOptions = {
expires: new Date(
Date.now() process.env.JWT_COOKIE_EXPIRES_IN * 60 * 1000
),
httpOnly: true,
secure: true
};
const refreshCookieOptions = {
expires: new Date(
Date.now()
process.env.REFRESH_TOKEN_COOKIE_EXPIRES_IN * 24 * 60 * 60 * 1000
),
httpOnly: true,
secure: true
};
console.log("right before creating cookies", Date.now())。
res.cookie("access-token", accessToken, accessCookieOptions)。
res.cookie("refresh-token", refreshToken, refreshCookieOptions)。
console.log("剛創建完cookie", Date.now())。
});
這就是我在控制臺中得到的結果
就在發送回應之前 1631544430242
[1] 就在創建cookies之前 1631544430324
[1] (node:11224) UnhandledPromiseRejectionWarning。錯誤[ERR_HTTP_HEADERS_SENT]。在頭檔案被發送到客戶端后無法設定頭檔案
如何在發送回應之前設定 cookie?
uj5u.com熱心網友回復:
由于catchAsync,createTokens函式立即回傳,盡管它涉及異步的Token.create。在它回傳后,res.json被執行,而res.cookie在Token.create也完成后才出現。這導致了錯誤的發生。
下面的例子說明了這一點:
const {catchAsync} = require("catch-async-express"/span>) 。
async function f() {
return new Promise(function(resolve, reject) {
setTimeout(resolve, 1000) 。
}).then(() => console.log(1))。
}
async function g() {
await catchAsync(f)()。
console.log(2)。
}
g()。
2被立即記錄,而1在1000ms的超時后被記錄。
避免在這里使用catchAsync。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/310214.html
標籤:
