Express密码验证异常:正确密码登录后任意密码均可访问问题排查
问题根源与修复方案
问题出在哪?
你代码里的userAuthorised是全局变量,Express服务器是单进程运行的,这个变量会被所有请求共用。一旦有一次输入正确密码把它设为true,之后所有请求(哪怕输入错误密码)都会读取到这个true值,自然就能登录了——而且这个变量永远不会被改回false,除非重启服务器。
再看逻辑细节:passCheck中间件会在每次请求时检查密码,匹配就把全局变量设为true,但/check路由只判断这个全局变量的状态,完全忽略当前请求的密码是否正确。这就导致只要有一次正确密码,后续所有请求都会被放行。
怎么修复?
有两种常用方案,按需选择:
方案1:直接在路由内验证(最简单)
删掉全局变量和passCheck中间件,直接在/check路由里验证当前请求的密码,确保每次请求都独立判断:
import express from "express"; import { dirname } from "path"; import { fileURLToPath } from "url"; const __dirname = dirname(fileURLToPath(import.meta.url)); import bodyParser from "body-parser"; const app = express(); app.use(bodyParser.urlencoded({extended: true})); app.get("/", (req, res) => { res.sendFile(__dirname + "/public/index.html"); }); app.post("/check", (req, res) => { console.log(req.body); // 直接校验当前请求的密码 if(req.body["password"] === "ILoveProgramming"){ res.sendFile(__dirname + "/public/secret.html"); } else { res.redirect("/"); } }); app.listen(3000, () => { console.log("Server Running on port 3000"); });
方案2:用会话跟踪用户状态(适合多用户场景)
如果需要让用户登录后保持状态(不用每次输入密码),可以使用express-session,每个用户的授权状态会存在独立的会话里,不会互相干扰:
- 先安装依赖:
npm install express-session - 修改代码:
import express from "express"; import { dirname } from "path"; import { fileURLToPath } from "url"; const __dirname = dirname(fileURLToPath(import.meta.url)); import bodyParser from "body-parser"; import session from "express-session"; const app = express(); // 配置会话,secret替换为自己的密钥 app.use(session({ secret: "your-own-secret-key", resave: false, saveUninitialized: false, cookie: { secure: false } // 开发环境用false,生产环境建议开启HTTPS后设为true })); app.use(bodyParser.urlencoded({extended: true})); app.get("/", (req, res) => { res.sendFile(__dirname + "/public/index.html"); }); app.post("/check", (req, res) => { console.log(req.body); if(req.body["password"] === "ILoveProgramming"){ // 把授权状态存入当前用户的会话 req.session.isAuthorized = true; res.sendFile(__dirname + "/public/secret.html"); } else { res.redirect("/"); } }); // 可选:添加路由保护,直接访问secret页面时检查会话状态 app.get("/secret", (req, res) => { if(req.session.isAuthorized){ res.sendFile(__dirname + "/public/secret.html"); } else { res.redirect("/"); } }); app.listen(3000, () => { console.log("Server Running on port 3000"); });
内容的提问来源于stack exchange,提问作者Bhawesh Pandey
相关产品推荐
相关产品推荐

