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开发, 双因素认证, 自定义脚本