JWT认证Fetch请求无Cookie时Pending问题排查
问题场景
开发基于JWT+Cookie认证的博客应用时遇到以下问题:
- 携带有效/无效Cookie发起认证请求时,服务端正常返回响应
- Cookie为空时,请求始终处于Pending状态,无任何响应返回
相关后端代码:
import jwt from "jsonwebtoken"; export const isAuthenticated = (req, res)=>{ { jwt.verify(req.cookies.token, process.env.SECRET, (err,user) => { if (err) return res.status(403); res.json(user).status(200); }); } } export const logout = (req,res)=>{ return res.cookie('token',"",{httpOnly:true,path:'/',sameSite:'none',secure:true}).json('ok') }
问题原因
当Cookie为空时,req.cookies.token的值为undefined,传入jwt.verify后,该方法会同步抛出错误(而非通过回调的err参数返回),导致后续回调逻辑完全无法执行,服务端也没有向客户端发送任何响应,最终请求一直挂起。
而当Cookie是无效字符串时,jwt.verify会正常调用回调并传入err,此时代码能执行return res.status(403),客户端能收到响应。
修复方案
方案1:提前校验Token存在性
在调用jwt.verify前先检查Token是否存在,避免传入undefined触发同步错误:
import jwt from "jsonwebtoken"; export const isAuthenticated = (req, res)=>{ // 无token直接返回403 if (!req.cookies.token) { return res.status(403).send("Authentication required"); } jwt.verify(req.cookies.token, process.env.SECRET, (err, user) => { if (err) return res.status(403).send("Invalid token"); // 先设置状态码再发送响应,原写法顺序有误 res.status(200).json(user); }); } export const logout = (req,res)=>{ // 添加maxAge:0确保浏览器立即删除Cookie return res.cookie('token', "", { httpOnly: true, path: '/', sameSite: 'none', secure: true, maxAge: 0 }).json('ok') }
方案2:使用try/catch捕获所有异常(推荐)
用try/catch包裹整个认证逻辑,既能处理undefinedToken的情况,也能覆盖其他可能的同步错误:
import jwt from "jsonwebtoken"; export const isAuthenticated = (req, res)=>{ try { const token = req.cookies.token; if (!token) throw new Error("No authentication token provided"); const user = jwt.verify(token, process.env.SECRET); res.status(200).json(user); } catch (err) { res.status(403).send(err.message || "Authentication failed"); } } export const logout = (req,res)=>{ return res.cookie('token', "", { httpOnly: true, path: '/', sameSite: 'none', secure: true, maxAge: 0 }).json('ok') }
额外说明
原代码中res.json(user).status(200)的写法存在问题,Express中应先设置状态码再发送响应,否则状态码可能不会被正确设置。
内容的提问来源于stack exchange,提问作者Sibichandru Rajendran
相关产品推荐
相关产品推荐

