最新版本的Express在Nodejs中使用csrf问题

最新版本的Express在Nodejs中使用csrf问题

app.js

/**
 * Module dependencies.
 */

var express = require('express');
var routes = require('./routes');
var user = require('./routes/user');
var http = require('http');
var path = require('path');

var app = express();

// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.json());
app.use(express.urlencoded());
app.use(express.methodOverride());
app.use(express.cookieParser('sdfs'));
app.use(express.session());
app.use(express.csrf());
app.use(function(req,res,next){
res.locals.token = req.csrfToken()
next();
});
app.use(app.router);
app.use(require('less-middleware')({ src: path.join(__dirname, 'public') }));
app.use(express.static(path.join(__dirname, 'public')));

// development only
if ('development' == app.get('env')) {
  app.use(express.errorHandler());
}

app.get('/', routes.index);
/**
 * 用户相关操作
 */
app.get('/users', user.list);
app.get('/reg',user.reg);
app.post('/disposeReg',user.disposeReg);


http.createServer(app).listen(app.get('port'), function(){
  console.log('Express server listening on port ' + app.get('port'));
});

页面使用

<input type=“hidden” name="_csrf" value="<%= token %>>">

一直提示430错误,然后看到吗csrf一直在变


2 回复

最新版本的Express在Node.js中使用CSRF问题

问题描述

在使用最新版本的Express时,尝试实现CSRF保护,但遇到了一些问题。具体来说,在表单提交时,始终收到430错误,并且发现每次请求的CSRF令牌都会发生变化。

解决方案

在最新版本的Express中,express.csrf()已经被移除,取而代之的是csurf中间件。下面是更新后的代码示例,展示了如何正确地使用CSRF保护。

更新后的代码

首先,安装csurf中间件:

npm install csurf --save

然后,更新你的app.js文件:

/**
 * Module dependencies.
 */

var express = require('express');
var routes = require('./routes');
var user = require('./routes/user');
var http = require('http');
var path = require('path');
var csrf = require('csurf');

var app = express();

// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.json());
app.use(express.urlencoded());
app.use(express.methodOverride());
app.use(express.cookieParser('sdfs'));
app.use(express.session());

// 创建一个新的csrf中间件实例
var csrfProtection = csrf({ cookie: true });

app.use(function(req, res, next) {
    res.locals.token = req.csrfToken();
    next();
});

app.use(app.router);
app.use(require('less-middleware')({ src: path.join(__dirname, 'public') }));
app.use(express.static(path.join(__dirname, 'public')));

// development only
if ('development' == app.get('env')) {
    app.use(express.errorHandler());
}

app.get('/', routes.index);

/**
 * 用户相关操作
 */
app.get('/users', user.list);
app.get('/reg', user.reg);
app.post('/disposeReg', csrfProtection, user.disposeReg); // 添加csrfProtection中间件

http.createServer(app).listen(app.get('port'), function() {
    console.log('Express server listening on port ' + app.get('port'));
});

页面中的使用

在你的HTML表单中,确保包含隐藏的CSRF令牌字段:

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

解释

  1. 引入csurf中间件:通过require('csurf')引入csurf中间件。
  2. 创建中间件实例:使用csrf({ cookie: true })创建一个CSRF中间件实例。
  3. 设置全局变量:在每个请求中设置res.locals.token为当前请求的CSRF令牌。
  4. 应用中间件:在需要CSRF保护的路由上应用csrfProtection中间件(例如app.post('/disposeReg', csrfProtection, user.disposeReg))。

这样,你就可以正确地在最新的Express版本中使用CSRF保护了。


最新的 Express 版本(如 4.x)已经将 express.csrf() 移除,并推荐使用 csurf 中间件来处理 CSRF 保护。下面是修改后的代码示例:

安装 csurf

首先需要安装 csurf 模块:

npm install csurf --save

修改 app.js

接下来,修改你的 app.js 文件,使用 csurf 中间件:

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

var app = express();

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

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

// 使用 csrf 中间件
app.use(csrfProtection);

// 其他中间件...
app.use(express.static(path.join(__dirname, 'public')));

// 在视图引擎中添加 csrf token
app.use(function (req, res, next) {
    res.locals.token = req.csrfToken();
    next();
});

// 路由定义...
app.get('/', function(req, res) {
    res.render('index', { csrfToken: req.csrfToken() });
});

app.listen(3000, function () {
    console.log('App is running on port 3000.');
});

页面使用

在 HTML 表单中使用 CSRF Token:

<form action="/disposeReg" method="POST">
    <input type="hidden" name="_csrf" value="<%= csrfToken %>">
    <!-- 其他表单字段 -->
</form>

解释

  1. 安装 csurf:我们首先安装 csurf 模块。
  2. 创建 csrf 保护中间件:使用 csrf() 函数创建一个中间件。
  3. 应用中间件:通过 app.use(csrfProtection) 应用到整个应用。
  4. 设置视图变量:在视图渲染时将 CSRF Token 设置为变量,以便在表单中使用。
  5. HTML 表单:在 HTML 表单中包含一个隐藏的 _csrf 字段,其值为视图中的 csrfToken

这样可以确保你的应用正确地处理 CSRF 保护,避免 403 错误。

回到顶部