Express框架如何阻止用户直接访问/success、/failure等路由?
实现方案
方案1:基于Session校验(最推荐)
核心逻辑是通过服务端会话记录用户是否完成了表单提交,只有携带有效提交标记的请求才能访问对应页面。
步骤1:安装express-session依赖
npm install express-session
步骤2:配置Session中间件
在你的Express启动代码中加入session配置:
const session = require('express-session'); // 配置session,生产环境请调整secret、存储方式等参数 app.use(session({ secret: '你的自定义加密字符串', // 替换为自己的随机密钥 resave: false, saveUninitialized: false, cookie: { maxAge: 5 * 60 * 1000 } // 有效期设为5分钟足够使用 }));
步骤3:修改表单提交处理逻辑
在你处理表单提交的路由中,处理完业务逻辑后,给session添加提交标记,再执行重定向:
app.post('/submit-form', function(req, res) { // 你原有处理表单、校验联系方式的逻辑 const isSubmitSuccess = 你的业务判断结果; // 比如校验通过为true,失败为false // 给session添加提交标记 req.session.formSubmitted = true; req.session.submitResult = isSubmitSuccess; if (isSubmitSuccess) { res.redirect('/success'); } else { res.redirect('/failure'); } });
步骤4:修改success/failure路由逻辑
添加校验逻辑,只有存在有效提交标记时才返回页面,否则重定向到表单页:
app.get("/success", function(req, res) { // 校验是否是表单提交后跳转的请求 if (req.session.formSubmitted && req.session.submitResult === true) { // 用完立即销毁标记,避免用户刷新、后退或直接输入地址再次访问 req.session.formSubmitted = null; req.session.submitResult = null; res.sendFile(__dirname + "/success.html"); } else { // 没有有效标记直接跳转到表单页 res.redirect('/你的表单页路由'); } }); app.get("/failure", function(req, res) { if (req.session.formSubmitted && req.session.submitResult === false) { req.session.formSubmitted = null; req.session.submitResult = null; res.sendFile(__dirname + "/failure.html"); } else { res.redirect('/你的表单页路由'); } });
方案2:轻量场景下的一次性Token校验
如果不想引入session依赖,可以在重定向时携带一次性校验token,服务端临时存储有效token:
// 服务端内存存储有效token,生产环境可以用redis替代 const validTokens = new Set(); // 表单提交路由逻辑 app.post('/submit-form', function(req, res) { const isSubmitSuccess = 你的业务判断结果; // 生成随机token const token = Math.random().toString(36).slice(2); validTokens.add(token); // 1分钟后自动销毁token setTimeout(() => validTokens.delete(token), 60 * 1000); if (isSubmitSuccess) { res.redirect(`/success?token=${token}`); } else { res.redirect(`/failure?token=${token}`); } }); // success路由示例 app.get("/success", function(req, res) { const token = req.query.token; if (token && validTokens.has(token)) { validTokens.delete(token); res.sendFile(__dirname + "/success.html"); } else { res.redirect('/你的表单页路由'); } });
注意事项
- 生产环境使用session时,不要用默认的内存存储,建议对接redis、mongodb等持久化存储,避免服务重启session丢失,同时要设置合理的cookie安全策略。
- 两种方案都会在用户第一次访问页面后销毁校验标记,即使是提交后跳转的用户,刷新页面也会失去访问权限,符合业务要求。
内容的提问来源于stack exchange,提问作者Very Confused
相关产品推荐
相关产品推荐

