Nodejs csrf from提交问题

Nodejs csrf from提交问题

提交后显示如下错误 Express

403 Error: invalid csrf token
at createToken (/home/lan/Desktop/node/MyBlog/node_modules/express/node_modules/connect/node_modules/csurf/index.js:73:19)
at Object.handle (/home/lan/Desktop/node/MyBlog/node_modules/express/node_modules/connect/node_modules/csurf/index.js:47:24)
at next (/home/lan/Desktop/node/MyBlog/node_modules/express/node_modules/connect/lib/proto.js:193:15)
at Object.staticMiddleware [as handle] (/home/lan/Desktop/node/MyBlog/node_modules/express/node_modules/connect/node_modules/serve-static/index.js:55:61)
at next (/home/lan/Desktop/node/MyBlog/node_modules/express/node_modules/connect/lib/proto.js:193:15)
at Object.methodOverride [as handle] (/home/lan/Desktop/node/MyBlog/node_modules/express/node_modules/connect/node_modules/method-override/index.js:48:5)
at next (/home/lan/Desktop/node/MyBlog/node_modules/express/node_modules/connect/lib/proto.js:193:15)
at multipart (/home/lan/Desktop/node/MyBlog/node_modules/express/node_modules/connect/lib/middleware/multipart.js:93:27)
at /home/lan/Desktop/node/MyBlog/node_modules/express/node_modules/connect/lib/middleware/bodyParser.js:64:9
at /home/lan/Desktop/node/MyBlog/node_modules/express/node_modules/connect/lib/middleware/urlencoded.js:73:7

app configure 如下

app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.set('view options', { layout: true });
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.cookieParser());
app.use(express.session({
    secret: "golb",
    cookie: { maxAge: 24 * 60 * 60 * 1000 },
    store: new mongoStore({
        url: utils.dbConnectionUrl(config.db)
    })
}));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.static(path.join(__dirname, 'public')));
app.use(express.csrf());
app.use(function(req, res, next) {
    res.locals.token = req.session._csrf;
    next();
});
app.use(function(req, res, next) {
    res.locals.session = req.session;
    next();
});

5 回复

在处理Node.js应用中的CSRF(跨站请求伪造)问题时,通常会使用csurf中间件来生成和验证CSRF令牌。根据你提供的错误信息和配置,我们可以看到你已经正确地安装并配置了csurf中间件,但仍然遇到了CSRF令牌无效的问题。

解决方案

首先,确保你正确地使用了csurf中间件,并且在表单中正确地包含了CSRF令牌。以下是修正后的配置和示例代码:

1. 配置 csurf 中间件

确保在你的应用中正确配置了csurf中间件。你可以将它放在bodyParser之后,这样可以确保解析请求体后再进行CSRF验证。

const express = require('express');
const csurf = require('csurf');
const bodyParser = require('body-parser');

const app = express();

// 使用body-parser中间件
app.use(bodyParser.urlencoded({ extended: false }));

// 创建一个csrf实例
const csrfProtection = csurf({ cookie: true });

// 在需要保护的路由前使用csrfProtection中间件
app.get('/form', csrfProtection, (req, res) => {
    res.render('form', { csrfToken: req.csrfToken() });
});

app.post('/submit', csrfProtection, (req, res) => {
    // 处理表单提交
    res.send('Form submitted successfully!');
});

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

2. 在表单中包含CSRF令牌

确保在HTML表单中正确地包含CSRF令牌。这可以通过在表单中添加一个隐藏字段来实现。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>CSRF Form</title>
</head>
<body>
    <h1>Submit a Form</h1>
    <form action="/submit" method="POST">
        <input type="hidden" name="_csrf" value="{{ csrfToken }}">
        <label for="name">Name:</label>
        <input type="text" id="name" name="name" required>
        <button type="submit">Submit</button>
    </form>
</body>
</html>

解释

  1. 配置 csurf:

    • 我们创建了一个名为csrfProtection的中间件,用于应用CSRF保护。
    • csrfProtection中间件应用到需要保护的路由上,例如/form/submit
  2. 在表单中包含CSRF令牌:

    • 在表单中添加一个隐藏的输入字段_csrf,其值为{{ csrfToken }}。这确保了每次表单提交时都包含有效的CSRF令牌。

通过以上步骤,你应该能够解决CSRF令牌无效的问题,并确保你的表单提交是安全的。


form 里也加了 input(type=‘hidden’, name=’_csrf’, value=’#{token}’) 新人刚接触node 昨天折腾了一下午 请求讲解 不甚感激!

同求你的问题,不知道楼主解决了没有?能否分享出来

这样改试试: res.locals.token = req.session._csrf; –> res.locals.token = req.csrfToken();

根据你提供的信息,你在使用 express.csrf() 中间件时遇到了 CSRF 令牌验证失败的问题。这通常是因为 CSRF 令牌没有正确地添加到你的表单或请求头中。

解决方案

  1. 确保 CSRF 令牌被添加到表单中: 在 HTML 表单中添加一个隐藏字段来包含 CSRF 令牌。

  2. 确保 CSRF 令牌被添加到 AJAX 请求中: 如果你使用 AJAX 提交表单,确保在请求头中添加 CSRF 令牌。

示例代码

1. 更新 HTML 表单

在你的 HTML 表单中添加一个隐藏字段来存储 CSRF 令牌:

<form action="/submit" method="POST">
    <input type="hidden" name="_csrf" value="{{token}}">
    <!-- 其他表单字段 -->
    <button type="submit">Submit</button>
</form>

2. 确保 CSRF 令牌被添加到 Express 路由处理程序中

确保你的路由处理程序中包含了 CSRF 令牌:

var express = require('express');
var csrf = require('csurf');
var bodyParser = require('body-parser');

var app = express();

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

app.use(bodyParser.urlencoded({ extended: false }));

app.get('/form', csrfProtection, function (req, res) {
    res.render('form', { token: req.csrfToken() });
});

app.post('/submit', csrfProtection, function (req, res) {
    // 处理表单提交
    res.send('Form submitted successfully');
});

app.listen(3000, function () {
    console.log('Server listening on port 3000');
});

3. 确保 CSRF 令牌被添加到 AJAX 请求中

如果你使用 AJAX 提交表单,确保在请求头中添加 CSRF 令牌:

$.ajax({
    url: '/submit',
    method: 'POST',
    data: {
        field1: 'value1',
        field2: 'value2'
    },
    headers: {
        'X-CSRF-Token': $('input[name="_csrf"]').val()
    },
    success: function (response) {
        console.log(response);
    }
});

解释

  • express.csrf() 生成并验证 CSRF 令牌。
  • res.locals.token 将 CSRF 令牌传递给视图模板。
  • 在表单中添加一个隐藏字段 <input type="hidden" name="_csrf" value="{{token}}"> 来包含 CSRF 令牌。
  • 对于 AJAX 请求,在请求头中添加 X-CSRF-Token

通过这些步骤,你应该能够解决 CSRF 令牌验证失败的问题。

回到顶部