You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NodeJS基于Promise的用户注册存文本文件代码求优化反馈

注册函数代码改进建议
  • 改用Promise风格文件API,消除回调嵌套
    Node.js的fs模块提供了fs.promises API,结合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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 07:10:31