sharveshsuresh71/secure-login-system

GitHub: sharveshsuresh71/secure-login-system

基于 Node.js/Express 的安全登录认证系统,通过参数化查询、密码哈希、会话管理、速率限制和可选 TOTP 双因素认证防御常见 Web 攻击。

Stars: 0 | Forks: 0

# 安全登录系统 一个实现安全身份验证的 Node.js/Express Web 应用程序: 哈希密码、输入验证、防 SQL 注入的数据库访问、带登出功能的会话 管理,以及可选的基于 TOTP 的双因素认证 (2FA)。 ## 功能 - **密码哈希** — 使用带有可配置成本因子(默认:12 轮)的 bcrypt。绝不存储明文密码。 - **SQL 注入防护** — 所有数据库查询均使用参数化语句(带有 `?` 占位符的 `better-sqlite3` 预处理语句)。任何地方都不与用户输入进行字符串拼接。 - **输入验证** — `express-validator` 强制执行用户名/邮箱格式、密码强度(长度 + 大小写混合 + 数字)以及匹配的密码确认,客户端和服务器端双重验证。 - **会话管理** — 存储在 SQLite 中的服务器端会话(`express-session` + `better-sqlite3-session-store`),具有以下特点: - `httpOnly`、`sameSite=lax` cookie - 在生产环境中自动强制使用 `secure` cookie - 登录时重新生成会话(防止会话固定) - 登出时彻底销毁会话 - **暴力破解防护** — 对身份验证 endpoint 进行速率限制(`express-rate-limit`),并且在 5 次登录失败后锁定账户(锁定 15 分钟)。 - **双因素认证 (2FA)** — 可选的 TOTP(兼容 Google Authenticator / Authy / 1Password),支持二维码注册(`speakeasy` + `qrcode`)。 - **安全标头** — `helmet` 设置合理的默认值(CSP、X-Frame-Options 等)。 - **通用错误消息** — 登录失败时绝不透露用户名是否存在。 ## 环境要求 - Node.js 18+(已在 Node 22 上测试) - npm ## 安装说明 ``` # 1. 安装依赖 npm install # 2. 创建你的环境文件 cp .env.example .env # 3. 生成一个强 session secret 并将其放入 .env openssl rand -hex 32 # 将输出粘贴为 .env 中的 SESSION_SECRET= # 4. 启动 app npm start ``` 应用程序将在 `http://localhost:3000` 提供。 SQLite 数据库文件(`db/app.db`、`db/sessions.db`)会在首次 运行时自动创建 — 无需手动设置数据库。 ## 项目结构 ``` secure-login-app/ ├── server.js # App entry point, middleware, security config ├── routes/ │ ├── auth.js # register / login / logout / 2FA login step │ └── dashboard.js # protected dashboard + 2FA setup/disable ├── middleware/ │ └── auth.js # requireAuth / redirectIfAuthenticated guards ├── db/ │ ├── database.js # SQLite connection + schema │ └── userModel.js # All user queries (parameterized) ├── utils/ │ └── validators.js # express-validator rules ├── views/ # EJS templates ├── public/css/style.css # Styling └── .env.example ``` ## 各项要求的实现方式 | 要求 | 实现 | |---|---| | 哈希密码 | `routes/auth.js` 中的 `bcrypt.hash(password, 12)`;使用 `bcrypt.compare` 进行验证 | | SQL 注入防护 | `db/userModel.js` 中的所有查询均通过 `better-sqlite3` 预处理语句使用 `?` 占位符 | | 输入验证 | `utils/validators.js` — 长度、字符集、邮箱格式、密码强度 | | 会话管理 | 带有 SQLite 后端存储的 `express-session`、`httpOnly`/`sameSite` cookie、登录时重新生成会话 | | 登出 | `POST /logout` 销毁会话并清除 cookie | | 2FA(可选) | 通过 `speakeasy` 实现 TOTP,通过 `qrcode` 进行二维码注册,以 ±30 秒的时间窗口容差进行验证 | ## 安全说明 / 生产环境检查清单 - 在生产环境中始终通过 HTTPS 运行 — 设置 `NODE_ENV=production` 以便 cookie 获得 `secure` 标志。 - 如果 `SESSION_SECRET` 被泄露请务必轮换,且切勿提交 `.env` 文件。 - 考虑为完整的生产系统添加邮箱验证和密码重置流程(此处未包含,以将范围集中在所要求的功能上)。 - 包含的速率限制是每个进程内存中的;对于多实例部署,请使用 Redis 作为其后端支持。 - 定期检查 `npm audit` 输出并保持依赖项的补丁更新。 ## 自行测试 1. 前往 `/register` 并创建一个账户(密码必须包含 10 个以上字符,且包含大小写字母和数字)。 2. 在 `/login` 登录。 3. 从仪表板中,点击 **启用双因素认证**,使用身份验证器应用扫描二维码,并输入 6 位代码进行确认。 4. 登出并重新登录 — 此时在输入密码后,系统将提示您输入 2FA 验证码。
标签:Express, GNU通用公共许可证, MITM代理, Node.js, SQLite, Syscall, Web开发, 双因素认证, 自定义脚本