使用jsonwebtoken中间件验证时出现jwt未提供错误的求助
JWT验证中间件无法获取Token的问题修复
问题背景
身份验证中间件使用jsonwebtoken做验证时,无法获取到Token,控制台输出"No token provided",报错JsonWebTokenError: jwt must be provided。数据库中已生成对应Token,但后端部署服务器后,本地localhost:8080运行也出现相同问题。
问题排查与修复方案
1. 前端请求未携带凭证
浏览器默认不会在跨域请求中携带Cookie,必须明确配置请求携带凭证:
- Axios请求配置:
axios.post('/api/v1/cart/addtocart/123', {}, { withCredentials: true }) - Fetch请求配置:
fetch('/api/v1/cart/addtocart/123', { method: 'POST', credentials: 'include' })
2. Cookie配置不完善
登录接口中设置Cookie时,缺少适配跨域的SameSite和Secure配置,导致Cookie无法在跨域场景下被正确传递:
修改loginController中的Cookie配置:
res.cookie("Amazon_website", token, { expires: new Date(Date.now() + 1800000), // 30分钟有效期 httpOnly: true, sameSite: process.env.NODE_ENV === 'production' ? 'none' : 'lax', secure: process.env.NODE_ENV === 'production', // 生产环境需HTTPS协议 });
本地开发使用HTTP协议时,
secure: true会导致Cookie无法设置,因此通过环境变量动态配置。
3. 中间件未先校验Token是否存在
当前中间件直接调用jwt.verify(token),若token为undefined会直接抛出错误,需先判断Token是否存在:
修改Authmiddleware.js:
const authmiddleware = async (req, res, next) => { try { const token = req.cookies.Amazon_website; // 先检查Token是否存在 if (!token) { return res.status(401).send("Unauthorized: No token provided"); } const verifyToken = jwt.verify(token, process.env.JWT_SECRET); const rootUser = await User.findOne({ _id: verifyToken._id, "tokens.token": token, }); if (!rootUser) { throw new Error("User Not Found"); } req.token = token; req.rootUser = rootUser; req.userID = rootUser._id; next(); } catch (error) { if (error.name === "TokenExpiredError") { res.status(401).send("Unauthorized: Token has expired"); } else { res.status(401).send("Unauthorized: No token provided"); } console.log(error); } };
4. 控制器方法调用拼写错误
addtocartController中调用的addTOCartData方法不存在,应为userModel中定义的addToCart:
// 原错误代码 const cartData = await userContact.addTOCartData(cart); // 修改后 const cartData = await userContact.addToCart(cart);
5. 重复的密码哈希钩子
userModel.js中有两个完全相同的pre("save")密码哈希钩子,会导致密码被重复哈希,保留一个即可:
userSchema.pre("save", async function (next) { if (this.isModified("password")) { const saltRounds = 12; this.password = await bcrypt.hash(this.password, saltRounds); this.cpassword = await bcrypt.hash(this.cpassword, saltRounds); } next(); });
内容的提问来源于stack exchange,提问作者user21744021
相关产品推荐
相关产品推荐

