使用csurf在非API路由函数中获取csrf token 解决未定义报错
错误原因
你的报错来自两个问题:
- 路由执行顺序问题:你当前全局注册的
checkUser中间件执行时机早于csrfProtection中间件,当checkUser中触发页面渲染时,req.csrfToken()方法还未被csurf库初始化,无法获取csrf token值。 - 渲染参数缺失:你在
checkUser中调用res.render渲染additional-user-info页面时,没有像/add路由一样传入csrfToken变量,模板读取不存在的变量自然抛出未定义错误。
另外你判断字段为空的代码中误用了按位或|,应该替换为逻辑或||避免逻辑判断异常。
修复方案
方案1:调整中间件+补全渲染参数
- 在app.js中把
csrfProtection调整为全局中间件,确保所有请求执行checkUser前已经初始化csrf能力:
// app.js中原有中间件顺序 app.use(cookieParser()); // 新增全局csrf中间件 var csrf = require("csurf"); var csrfProtection = csrf({ cookie: true }); app.use(csrfProtection); // 后续的路由顺序无需调整,/add路由可以去掉单独挂载的csrfProtection app.get("*", checkUser); app.get("/add", (req, res) => { console.log("zeeeeeeeee"); console.log(req.csrfToken()); res.render("additional-user-info", { csrfToken: req.csrfToken() }); });
- 修改authMiddleware.js中的渲染逻辑,补全csrfToken参数,同时修正逻辑运算符:
if ( user.additionalinfo.fullname == "" || user.additionalinfo.address == "" || user.additionalinfo.city == "" || user.additionalinfo.district == "" || user.additionalinfo.propertytype == "" || user.additionalinfo.adharcard == "" || user.additionalinfo.pancard == "" ) { return res.render("additional-user-info", { csrfToken: req.csrfToken() }); }
方案2:重定向到现有/add路由(更推荐)
不需要修改中间件顺序,直接将checkUser中的渲染逻辑改为重定向到已经适配了csrf的/add路由,逻辑更统一,无需维护两份渲染代码:
if ( user.additionalinfo.fullname == "" || user.additionalinfo.address == "" || user.additionalinfo.city == "" || user.additionalinfo.district == "" || user.additionalinfo.propertytype == "" || user.additionalinfo.adharcard == "" || user.additionalinfo.pancard == "" ) { return res.redirect('/add'); }
内容的提问来源于stack exchange,提问作者Skrillex
相关产品推荐
相关产品推荐

