使用Node.js与MongoDB实现Express表单认证时正确凭证提示无效求助
问题根因
- MongoDB的
find().toArray()方法返回的是Promise对象,你没有等待异步操作完成就直接读取length属性,此时Promise还处于pending状态,没有实际的查询结果数组,因此判断ob.length > 0永远为假,导致验证失败。 - 登录验证失败时你只在控制台打印日志,没有给前端返回响应,会导致前端请求超时无反馈。
- 注册表单的所有输入框都没有设置
name属性,就算后续开发注册接口,后台也无法获取表单提交的注册数据。 - 每次登录请求都新建MongoDB连接,会导致资源浪费、请求性能下降,建议全局复用连接。
- 密码明文存储在数据库中存在严重安全隐患,后续建议使用bcrypt等库对密码做哈希加密后再存储。
修复后的服务端核心代码
var express = require('express'); var app = express(); var fs = require('fs'); var MongoClient = require('mongodb').MongoClient; var bodyParser = require('body-parser') app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: true })); var mongo_profiles_url = 'mongodb+srv://signup:vesh2021@raspberry-target.7qt1j.mongodb.net/user-profiles?retryWrites=true&w=majority'; // 全局复用MongoDB连接 let dbInstance = null; // 初始化数据库连接 MongoClient.connect(mongo_profiles_url).then(db => { dbInstance = db.db("PAL"); console.log("MongoDB连接成功"); }).catch(err => { console.error("MongoDB连接失败", err); }); async function createDocument(clction, obj) { return dbInstance.collection(clction).insertOne(obj); } app.get('/', function (req, res) { fs.readFile('./login-signup.html', function(err, data) { if(err) { res.writeHead(500, {'Content-Type': 'text/html'}); return res.end("页面加载失败"); } res.writeHead(200, {'Content-Type': 'text/html'}); res.end(data) }); }); // 给login接口添加async关键字支持await app.post('/login', async function (req, res) { try { var inuser = req.body.loginUser; var inpass = req.body.loginPass; var myobj = { "user": inuser, "pass": inpass }; console.log(`Login credentials: ` + JSON.stringify(myobj)); // 等待异步查询完成获取结果数组 const ob = await dbInstance.collection("user-profiles").find(myobj).toArray(); console.log(ob); if (ob.length > 0) { fs.readFile('./home.html', function(err, data) { if(err) { res.writeHead(500, {'Content-Type': 'text/html'}); return res.end("首页加载失败"); } res.writeHead(200, {'Content-Type': 'text/html'}); res.end(data) }); } else { console.log("Incorrect credentials given.") res.writeHead(401, {'Content-Type': 'text/html'}); res.end("用户名或密码错误,请返回重试") } } catch (err) { console.error("登录处理出错", err); res.writeHead(500, {'Content-Type': 'text/html'}); res.end("服务器内部错误") } }); app.listen(1000, function () { console.log("Server listening to http://localhost:1000"); });
注册表单修复建议
给注册表单的所有输入框添加对应name属性,示例如下:
<input type="text" id="signupUsername" name="signupUsername" placeholder="Username" /> <input type="email" id="signupEmail" name="signupEmail" placeholder="Email" /> <input type="password" id="signupPassword" name="signupPassword" placeholder="Password" /> <input type="number" id="signupAge" name="signupAge" placeholder="Age" /> <input type="date" id="signupDOB" name="signupDOB">
内容的提问来源于stack exchange,提问作者viewy
相关产品推荐
相关产品推荐

