Node.js使用ftp-srv搭建FTP服务无法正确识别登录用户故障
ftp-srv 读取JSON账号配置连接失败、定时重启方案失效修复
问题根因
现有代码存在4个核心错误,直接导致认证失效、服务异常:
- 逻辑完全偏离预期:
setInterval(fa,1)每1毫秒执行一次,操作是给服务重复绑定login事件监听器,根本不是重启服务。Node.js的事件机制不会覆盖旧监听器,会按绑定顺序依次执行所有回调,短时间内会堆积几十万条重复监听器,直接拖垮进程内存、导致认证逻辑乱序。 - 账号比对逻辑写错:判断条件里的
'data["username"]'是固定字符串,不是读取data对象里的username字段,永远不可能匹配到用户输入的账号。 - 错误类引用缺失:代码里直接用
errors.GeneralError但没有引入对应错误对象,触发认证失败时会直接抛引用错误,中断连接流程。 - 配置逻辑冗余:要实现JSON配置的热读取,根本不需要重启服务、不需要重复绑定事件,在认证回调里实时读取最新配置即可。
正确实现代码
假设你的JSON账号配置存在同目录ftp-account.json文件,格式如下:
{ "username": "admin", "password": "Xserewer", "rootDir": "/home/" }
服务端代码修正后如下:
const FtpSrv = require('ftp-srv'); const fs = require('fs'); const path = require('path'); const port = 21; const ftpServer = new FtpSrv({ url: `ftp://0.0.0.0:${port}`, anonymous: false // 开启账号认证时关闭匿名登录 }); // 仅绑定一次login事件监听器,不要重复绑定 ftpServer.on('login', ({ username, password }, resolve, reject) => { try { // 每次用户登录时实时读取JSON配置,天然支持热更新,无需重启服务 const accountConf = JSON.parse( fs.readFileSync(path.join(__dirname, 'ftp-account.json'), 'utf8') ); // 正确读取配置字段做比对 if (username === accountConf.username && password === accountConf.password) { return resolve({ root: accountConf.rootDir }); } return reject(new FtpSrv.ERRORS.GeneralError('Invalid username or password', 401)); } catch (err) { console.error('认证流程异常:', err); return reject(new FtpSrv.ERRORS.GeneralError('Internal service error', 500)); } }); ftpServer.listen().then(() => { console.log(`FTP service started, listen on port ${port}`); });
注意事项
- 21端口属于系统特权端口,Linux/macOS环境下启动服务需要root权限,否则会报端口绑定失败。
- 如果JSON账号配置是存在内存变量中而非文件,直接在login回调里读取该变量的最新值即可,事件回调执行时会自动获取当前作用域下的最新变量值,不需要额外做重载操作。
- 业务场景下禁止设置1毫秒间隔的定时器,该频率会占满单线程CPU资源,直接导致服务无响应。
- 给EventEmitter绑定事件前要确认没有重复绑定,否则会出现回调多次执行的异常。
内容的提问来源于stack exchange,提问作者MihailCapone
相关产品推荐
相关产品推荐

