You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Express.js中csrfProtection未定义问题求助及Router解决记录

问题描述

作为Express/Node.js新手,我尝试在index.js中引入app.js和myCustomCsrf.js,但运行时抛出错误:ReferenceError: csrfProtection is not defined。以下是三个文件的原始代码:

index.js

const app = require("./app.js");

const PORT = 5000
app.listen(PORT)


require("./myCustomCsrf.js")


app.get('/*', function(req, res) {
    res.sendFile(path.join(__dirname, '/build/index.html'), function(err) {
        if (err) {
            res.status(500).send(err)
        }
    })
})

app.js

const express = require('express')
const path = require('path')

const mysql = require('mysql');

const crypto = require('crypto');

const cookieParser = require('cookie-parser')
const csrf = require('csurf')
const bodyParser = require('body-parser')
const cors = require('cors')
const session = require('express-session');
const { generateKey } = require('crypto');

// setup route middlewares
const csrfProtection = csrf({ cookie: true })
const parseForm = bodyParser.urlencoded({ extended: false })

// create express app
const app = express()

const corsOptions = {
    origin: "http://localhost:3000",
    credentials: true,
}

app.use(cors(corsOptions));

// setup session
app.use(session(
    {
        key: "guestSession",
        secret: "yourSecretHere",
        resave: false,
        saveUninitialized: false,
        cookie: {
            maxAge: 1000 * 60 * 60 * 24
        }
    }
))

// parse cookies
// we need this because "cookie" is true in csrfProtection
app.use(cookieParser())

app.use(express.static(path.join(__dirname + "/public")))
app.use(express.json())



module.exports = app

myCustomCsrf.js

const app = require("../app");

// set his csrf value in useState in frontend (react)
app.get("/api/checkguest", csrfProtection, (req, res) => {
    res.send({value: req.csrfToken() })
});
错误原因
  1. 作用域问题:csrfProtection是app.js内部定义的局部变量,myCustomCsrf.js无法直接访问该变量,导致引用错误。
  2. 路径错误:myCustomCsrf.js中使用require("../app"),若myCustomCsrf.js与app.js在同一目录下,正确路径应为require("./app"),否则会找不到app.js文件。
  3. index.js遗漏依赖:index.js中使用了path模块但未引入,会导致后续res.sendFile执行报错。
正确的文件组织与引入方式

方法1:导出并共享csrfProtection

通过修改app.js导出csrfProtection,让myCustomCsrf.js可以直接引入使用:

修改app.js

在文件末尾修改导出语句,同时导出app和csrfProtection:

module.exports = { app, csrfProtection };

修改myCustomCsrf.js

修正路径并引入所需变量:

const { app, csrfProtection } = require("./app");

app.get("/api/checkguest", csrfProtection, (req, res) => {
    res.send({value: req.csrfToken() })
});

修改index.js

调整引入方式并补充path模块:

const { app } = require("./app.js");
const path = require('path');

const PORT = 5000;

// 确保先加载路由再启动服务
require("./myCustomCsrf.js");

app.get('/*', function(req, res) {
    res.sendFile(path.join(__dirname, '/build/index.html'), function(err) {
        if (err) {
            res.status(500).send(err)
        }
    })
});

app.listen(PORT);

方法2:使用Express Router(推荐)

这是更符合模块化开发的方案,通过Router解耦路由与app实例,避免直接依赖全局变量:

修改myCustomCsrf.js

创建Router实例并定义路由,可自行初始化csrfProtection或从app.js引入:

const express = require('express');
const csrf = require('csurf');
const router = express.Router();

// 初始化csrf保护中间件(也可从app.js导出引入)
const csrfProtection = csrf({ cookie: true });

router.get("/api/checkguest", csrfProtection, (req, res) => {
    res.send({value: req.csrfToken() })
});

module.exports = router;

修改app.js

在合适位置(中间件挂载完成后)引入并挂载Router:

// 在app.js末尾、module.exports之前添加
const csrfRouter = require('./myCustomCsrf');
app.use(csrfRouter);

module.exports = app;

修改index.js

无需单独引入myCustomCsrf.js,只需确保app.js已正确挂载路由,同时补充path模块:

const app = require("./app.js");
const path = require('path');

const PORT = 5000;

app.get('/*', function(req, res) {
    res.sendFile(path.join(__dirname, '/build/index.html'), function(err) {
        if (err) {
            res.status(500).send(err)
        }
    })
});

app.listen(PORT);

方法3:通过函数参数传递依赖

将app和csrfProtection作为参数传递给myCustomCsrf.js,适合简单场景:

修改myCustomCsrf.js

改为导出一个函数,接收依赖参数:

module.exports = function(app, csrfProtection) {
    app.get("/api/checkguest", csrfProtection, (req, res) => {
        res.send({value: req.csrfToken() })
    });
};

修改index.js

调整引入逻辑,传递所需参数:

const { app, csrfProtection } = require("./app.js");
const path = require('path');

const PORT = 5000;

// 传递app和csrfProtection给路由模块
require("./myCustomCsrf.js")(app, csrfProtection);

app.get('/*', function(req, res) {
    res.sendFile(path.join(__dirname, '/build/index.html'), function(err) {
        if (err) {
            res.status(500).send(err)
        }
    })
});

app.listen(PORT);
额外注意事项
  • 中间件顺序:确保cookieParser、session等中间件在csrfProtection之前挂载,否则无法生成有效的CSRF Token。
  • 启动顺序:建议先加载所有路由和中间件,再调用app.listen()启动服务,避免路由未注册完成。

内容的提问来源于stack exchange,提问作者Galbert

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 04:35:55