exports.checkTokenMW = async (req, res, next) => {
try{
const token = req.cookies["access"]
const authData = await this.verifyAccessToken(token);
console.log(authData, "checkingTokenmw")
res.json(authData)
}catch(err){
res.status(401);
}
next()
};
exports.verifyAccessToken = async (accessToken) => {
return new Promise((resolve, reject) => {
jwt.verify(accessToken, keys.accessTokenSecret, (err, authData) => {
if(err){
console.log(err)
return reject(createError.Unauthorized());
}
console.log(authData, "accesstoken")
return resolve(authData);
});
})
};
exports.verifyRefreshToken = async (refreshToken, res) => {
return new Promise((resolve, reject) =>{
//const refreshToken = req.body.refreshToken;
jwt.verify(refreshToken, keys.refreshTokenSecret, (err, authData) =>{
if (err) { reject(createError.Unauthorized()); return }
const userId = authData.userId
return resolve(userId)
})
})
};
exports.logOut = async (req, res) => {
try{
console.log("----------- logout")
const refreshToken = req.cookies["refresh"];
if(!refreshToken) {throw createError.BadRequest();}
const user = await this.verifyRefreshToken(refreshToken);
res.clearCookie("refresh")
res.clearCookie("access")
res.sendStatus(204);
res.redirect("/");
return res.send()
}catch(err){
console.log(err)
}
};
**路由檔案有類似這樣的代碼**
app.get('/api/logout', authService.checkTokenMW,authService.logOut)
一段時間以來,我一直在嘗試解決此錯誤,但不確定哪個標頭多次設定自己
**這里是錯誤**
**
> Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
> at ServerResponse.setHeader (_http_outgoing.js:561:11)
> at ServerResponse.header (E:\COURSE-WEBSITE\main-backend\wiz_backend\node_modules\express\lib\response.js:771:10)
> at ServerResponse.append (E:\COURSE-WEBSITE\main-backend\wiz_backend\node_modules\express\lib\response.js:732:15)
> at ServerResponse.res.cookie (E:\COURSE-WEBSITE\main-backend\wiz_backend\node_modules\express\lib\response.js:857:8)
> at ServerResponse.clearCookie (E:\COURSE-WEBSITE\main-backend\wiz_backend\node_modules\express\lib\response.js:804:15)
> at exports.logOut (E:\COURSE-WEBSITE\main-backend\wiz_backend\controllers\auth-controller.js:131:13)
> at processTicksAndRejections (internal/process/task_queues.js:95:5) {
> code: 'ERR_HTTP_HEADERS_SENT'
> }
**
uj5u.com熱心網友回復:
問題出在中間件函式內部。檢查 authData 后,您無需使用res.json(authData). 因為在發送回應之后,next()無論如何都會觸發您的功能。由于next()將被呼叫,您的路由處理程式還將嘗試發送另一個回應,這是您面臨的沖突。同時,在catch塊中,需要有return陳述句,所以函式執行會停止,直到next()
exports.checkTokenMW = async (req, res, next) => {
try{
const token = req.cookies["access"]
const authData = await this.verifyAccessToken(token);
console.log(authData, "checkingTokenmw")
// res.json(authData) // <- remove this line
}catch(err){
return res.status(401); // <- here
}
next()
};
uj5u.com熱心網友回復:
當您的代碼嘗試向給定的傳入請求發送多個回應時,會導致您報告的特定錯誤。每個請求您只能發送一個回應。因此,所有代碼路徑(包括錯誤代碼路徑)都必須非常小心,以確保您發送的正是一個回應。
另外,如果您已經發送了回應,請不要呼叫next(),因為這將繼續路由到其他請求并最終嘗試發送一些回應(如果沒有其他處理程式匹配,則為 404)。
考慮到這些,您的代碼有幾個地方需要修復。
在您的 checkTokenWM 中:
exports.checkTokenMW = async (req, res, next) => {
try{
const token = req.cookies["access"]
const authData = await this.verifyAccessToken(token);
console.log(authData, "checkingTokenmw")
res.json(authData)
}catch(err){
res.status(401);
}
next()
};
你在打電話res.json(authData),然后也在打電話next()。但是,如果這樣做的目的是成為繼續路由的中間件,那么如果令牌通過,您不應該在此處發送任何回應。
然后,在 catch 塊中,您正在設定狀態,但不發送回應 - 這在技術上并沒有錯,但可能不是您想要的。我建議像這樣修復這兩個:
exports.checkTokenMW = async (req, res, next) => {
try{
const token = req.cookies["access"]
const authData = await this.verifyAccessToken(token);
console.log(authData, "checkingTokenmw");
// the access token verified so continue routing
next();
}catch(err){
// token did not verify, send error response
res.sendStatus(401);
}
};
在您的注銷中:
exports.logOut = async (req, res) => {
try{
console.log("----------- logout")
const refreshToken = req.cookies["refresh"];
if(!refreshToken) {throw createError.BadRequest();}
const user = await this.verifyRefreshToken(refreshToken);
res.clearCookie("refresh")
res.clearCookie("access")
res.sendStatus(204);
res.redirect("/");
return res.send()
}catch(err){
console.log(err)
}
};
您嘗試在成功注銷時發送三個回應,而在出錯時不回應。
首先,res.sendStatus(204)設定狀態并發送一個空回應。 res.status(204)如果您打算這樣做,則只會為實際發送回應的未來呼叫設定狀態。但是,在那種狀態下,你不能這樣做res.redirect()。
目前尚不清楚您要在這里做什么。如果你想重定向,那么它必須是 3xx 狀態,所以你不能使用 204。我假設你想做一個重定向。
我建議通過更改為修復:
exports.logOut = async (req, res) => {
try{
console.log("----------- logout")
const refreshToken = req.cookies["refresh"];
if(!refreshToken) {throw createError.BadRequest();}
const user = await this.verifyRefreshToken(refreshToken);
res.clearCookie("refresh");
res.clearCookie("access");
res.redirect("/");
}catch(err){
// can't call logout, if you weren't logged in
res.sendStatus(401);
}
};
僅供參考,如果您未登錄,大多數應用程式不會將呼叫注銷作為錯誤。它們只會清除 cookie 并以任何一種方式重定向到主頁,因為無論它們以前是否登錄都沒有問題。以您的方式執行此操作的問題是,如果 cookie 以某種方式損壞,那么您的代碼不會讓用戶嘗試通過注銷并重新登錄來清除問題。
所以,我可能會完全跳過令牌檢查:
exports.logOut = async (req, res) => {
res.clearCookie("refresh");
res.clearCookie("access");
res.redirect("/");
};
而且,我也會改變這個:
app.get('/api/logout', authService.checkTokenMW,authService.logOut)
對此:
app.get('/api/logout', authService.logOut);
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/410958.html
標籤:
上一篇:迭代HTML部分
