在express中使用csurf时,如果验证错误如何获取Nodejs异常?

在express中使用csurf时,如果验证错误如何获取Nodejs异常?

代码如下:

app.use(csrf());

app.post('/post', function(req, res){
    res.send(req.body.test).end();
})

app.get('/', function(req, res){
    console.log(req.csrfToken());
    res.send('<form method="post" action="/post"><input type="text" name="test"><input type="submit"><input type="hidden" name="_csrf" value="'+req.csrfToken()+'">  </form>');
});

如果表单中不包括_csrf会导致node中一个异常。我想当异常触发则转发到一个错误页面,而不是将异常输出出来。。这个怎么搞?


3 回复

在Express应用中使用csurf中间件来防止跨站请求伪造(CSRF)攻击时,如果表单提交中缺少必要的_csrf令牌,将会触发一个异常。为了更好地处理这种异常,并将其重定向到一个自定义的错误页面,你可以通过以下步骤来实现。

首先,你需要安装csurf中间件:

npm install csurf

接下来,我们需要创建一个错误处理器来捕获由csurf中间件抛出的异常。以下是修改后的代码示例:

const express = require('express');
const csrf = require('csurf');

const app = express();

// 创建 CSRF 保护中间件
const csrfProtection = csrf({ cookie: true });

// 设置视图引擎(例如 EJS)
app.set('view engine', 'ejs');

// 使用 CSRF 保护中间件
app.use(csrfProtection);

app.post('/post', function (req, res) {
    res.send(req.body.test).end();
});

app.get('/', function (req, res) {
    res.send(`
        <form method="post" action="/post">
            <input type="text" name="test">
            <input type="submit">
            <input type="hidden" name="_csrf" value="${req.csrfToken()}">
        </form>
    `);
});

// 错误处理器
app.use(function (err, req, res, next) {
    if (err.code === 'EBADCSRFTOKEN') { // 检查是否为 CSRF 错误
        res.status(403); // 设置状态码为 403
        res.render('error', { message: 'CSRF token is missing or invalid.' }); // 渲染错误页面
    } else {
        next(err); // 如果不是 CSRF 错误,则继续传递给下一个错误处理器
    }
});

// 启动服务器
app.listen(3000, () => {
    console.log('Server is running on port 3000');
});

在这个示例中,我们添加了一个错误处理器来捕获由csurf中间件抛出的异常。当检测到EBADCSRFTOKEN错误代码时,表示发生了CSRF验证错误。此时,我们将HTTP状态码设置为403,并渲染一个包含错误消息的自定义错误页面。这样可以避免直接向客户端暴露详细的错误信息,同时提供更好的用户体验。


求救啊哭。。。

在Express中使用csurf中间件时,可以通过处理csurf生成的错误来实现这一点。当你忘记包含CSRF令牌时,csurf会抛出一个错误,你可以通过next()函数捕获这个错误,并将其转发到错误处理中间件。

示例代码

  1. 安装依赖

    npm install express csurf
    
  2. 设置Express应用

    const express = require('express');
    const csrf = require('csurf');
    const app = express();
    
    // 创建 CSRF 保护中间件
    const csrfProtection = csrf({ cookie: true });
    
    // 使用 CSRF 保护
    app.use(express.urlencoded({ extended: false }));
    app.use(csrfProtection);
    
    // 错误处理中间件
    app.use(function(err, req, res, next) {
      if (err.code === 'EBADCSRFTOKEN') {
        // 捕获 CSRF 验证错误
        res.status(403);
        res.send('CSRF token missing or invalid.');
      } else {
        // 其他错误处理
        next(err);
      }
    });
    
    // 处理 POST 请求
    app.post('/post', function(req, res) {
      res.send(req.body.test).end();
    });
    
    // 渲染表单
    app.get('/', function(req, res) {
      console.log(req.csrfToken());
      res.send(`<form method="post" action="/post">
          <input type="text" name="test">
          <input type="submit">
          <input type="hidden" name="_csrf" value="${req.csrfToken()}">
        </form>`);
    });
    
    // 启动服务器
    app.listen(3000, () => {
      console.log('Server is running on port 3000');
    });
    

解释

  1. 安装依赖:首先确保安装了expresscsurf
  2. 创建 CSRF 保护中间件:使用csurf创建一个中间件csrfProtection
  3. 使用 CSRF 保护:在应用中使用csrfProtection中间件。
  4. 错误处理中间件:定义一个错误处理中间件来捕获csurf抛出的错误。如果错误码是EBADCSRFTOKEN,表示缺少或无效的CSRF令牌,此时返回一个错误页面(例如403 Forbidden)。
  5. 处理 POST 请求:在POST请求中,正常处理请求数据。
  6. 渲染表单:在GET请求中,渲染带有CSRF令牌的表单。
  7. 启动服务器:启动Express服务器。

这样,当表单中缺少CSRF令牌时,用户会被重定向到一个自定义的错误页面,而不是看到Node.js的异常堆栈。

回到顶部