如何在XMLHttpRequest的GET请求中传递密码参数并完成验证
解决bcrypt密码验证及请求参数传递问题
先梳理你现有代码的核心问题
- GET请求的参数存储在
req.query中,而非req.password,且你代码里的password变量未定义 bcrypt.compare是异步方法,必须用await才能拿到真实的布尔对比结果- GET请求没有请求体,
Account.find(req.body.username)无法正确获取用户名,应该从路由参数req.params.username取值 - 前后端错误提示文本不匹配(后端返回
Incorrect Password,前端判断Invalid password)
方案1:基于现有GET请求修正(不推荐,密码暴露风险高)
后端修正代码
router.get('/:username', getAcc, async (req, res) => { // 从路由参数获取用户名 const user = await Account.find({ username: req.params.username }); // 处理用户不存在的情况 if (!user || user.length === 0) { return res.json('User not found'); } // 从URL查询参数中取密码 const inputPassword = req.query.password; console.log(inputPassword); // 异步对比密码,必须加await const check = await bcrypt.compare(inputPassword, user[0].password); if (!check) { return res.json('Incorrect Password'); } res.json(res.acc); })
前端修正代码
const url = `http://localhost:3000/config/${username}`; const request = new XMLHttpRequest(); // 用encodeURIComponent处理密码中的特殊字符,同时统一错误判断文本 request.open("GET", `${url}?password=${encodeURIComponent(password)}`, true); request.send(); request.onload = function() { let jsonResponse = request.response; if (jsonResponse === 'Incorrect Password') { return alert('Invalid password'); } try { let parsedRes = JSON.parse(jsonResponse); alert(JSON.stringify(parsedRes)); } catch (e) { alert(jsonResponse); } }
方案2:改用POST请求(强烈推荐,安全度更高)
GET请求的参数会暴露在URL中,极易被日志、浏览器历史记录捕获,敏感信息必须通过POST请求体传递。
后端POST路由代码
// 新建登录路由,接收用户名和密码 router.post('/login', getAcc, async (req, res) => { // 从请求体中解构用户名和密码 const { username, password } = req.body; const user = await Account.find({ username }); if (!user || user.length === 0) { return res.json('User not found'); } // 异步对比密码 const check = await bcrypt.compare(password, user[0].password); if (!check) { return res.json('Incorrect Password'); } res.json(res.acc); })
前端POST请求代码
const url = `http://localhost:3000/config/login`; const request = new XMLHttpRequest(); request.open("POST", url, true); // 设置请求头为JSON格式 request.setRequestHeader("Content-Type", "application/json"); // 把用户名和密码打包成JSON字符串发送 const data = JSON.stringify({ username, password }); request.send(data); request.onload = function() { let jsonResponse = request.response; if (jsonResponse === 'Incorrect Password') { return alert('Invalid password'); } try { let parsedRes = JSON.parse(jsonResponse); alert(JSON.stringify(parsedRes)); } catch (e) { alert(jsonResponse); } }
关键注意事项
- 永远不要用GET传递敏感信息,密码这类数据必须放在POST请求体内
bcrypt.compare是异步函数,必须用await或.then()处理,直接拿返回值会得到Promise对象而非布尔值- 必须处理用户不存在的边界情况,避免后续代码报错
- 前后端的错误提示文本要统一,否则判断逻辑会失效
内容的提问来源于stack exchange,提问作者Dorritos
相关产品推荐
相关产品推荐

