NodeJS基于Promise的用户注册存文本文件代码求优化反馈
注册函数代码改进建议
改用Promise风格文件API,消除回调嵌套
Node.js的fs模块提供了fs.promisesAPI,结合async/await可以替代回调写法,避免回调地狱,让代码结构更清晰、更易维护。精确匹配用户名,避免误判
当前用data.includes(\username:${username} -`)的匹配逻辑存在漏洞:比如用户名为henry-时会被误判为已存在,或者文件中有henry用户时,henry1`也可能被错误匹配。建议按行分割文件内容,用精确的前缀匹配判断用户是否存在:const users = data.split(os.EOL).filter(line => line.trim() !== ''); const userExists = users.some(line => line.startsWith(`username:${username} -`));绝对禁止明文存储密码
明文存储密码是严重的安全隐患,必须使用哈希算法(如bcrypt)对密码进行哈希后再存储。示例:const bcrypt = require('bcrypt'); const saltRounds = 10; const hashedPassword = await bcrypt.hash(password, saltRounds); // 存储hashedPassword而非原密码处理并发注册的竞态条件
多个请求同时注册时,可能出现同时读取文件、都判断用户不存在后写入的情况,导致重复注册。可以通过文件锁工具(如lockfile库)或者改用数据库解决。如果坚持用文件存储,可尝试用fs.promises.writeFile的flag: 'wx'(仅文件不存在时写入)配合内容检查,但这种方式无法完全规避并发问题,更可靠的方案是使用数据库。抽离重复逻辑,提升代码复用性
原代码中写入用户信息的逻辑在writeFile和appendFile中重复,可抽成单独函数减少冗余:async function writeUserToFile(filePath, username, hashedPassword) { const userLine = `username:${username} - password:${hashedPassword}${os.EOL}`; try { await fs.promises.access(filePath); await fs.promises.appendFile(filePath, userLine, 'utf-8'); } catch (err) { if (err.code === 'ENOENT') { await fs.promises.writeFile(filePath, userLine, 'utf-8'); } else { throw err; } } }
改进后的完整代码示例
const fs = require('fs').promises; const os = require('os'); const bcrypt = require('bcrypt'); const DATA_BASE_FILE_PATH = './database.txt'; const saltRounds = 10; async function register(username, password) { // 哈希密码 const hashedPassword = await bcrypt.hash(password, saltRounds); let data; try { data = await fs.readFile(DATA_BASE_FILE_PATH, 'utf-8'); } catch (err) { if (err.code !== 'ENOENT') { throw err; } // 文件不存在,直接写入新用户 await fs.writeFile(DATA_BASE_FILE_PATH, `username:${username} - password:${hashedPassword}${os.EOL}`, 'utf-8'); return 'Saved username and password.'; } // 精确检查用户是否存在 const users = data.split(os.EOL).filter(line => line.trim() !== ''); const userExists = users.some(line => line.startsWith(`username:${username} -`)); if (userExists) { throw new Error(`"${username}" username already exists.`); } // 追加新用户信息 await fs.appendFile(DATA_BASE_FILE_PATH, `username:${username} - password:${hashedPassword}${os.EOL}`, 'utf-8'); return 'Saved username and password.'; } // 使用示例 register("henry", "qwerty123") .then((data) => console.log(data)) .catch((err) => console.log(err.message));
内容的提问来源于stack exchange,提问作者T D
相关产品推荐
相关产品推荐

