node.js 快速 CSRF 令牌验证
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/33060044/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Express CSRF token validation
提问by salep
I'm having issues with CSRF tokens. When I submit a form, a new XSRF-TOKENis being generated but I think I'm generating two different tokens, I'm kinda confused. There's also a token called _csrf, so I see two different cookies in developer tools (XSRF-TOKEN and _csrf), _csrfdoesn't change after a post.
我在使用 CSRF 令牌时遇到问题。当我提交表单时,XSRF-TOKEN正在生成一个新的,但我想我正在生成两个不同的令牌,我有点困惑。还有一个名为 的令牌_csrf,所以我在开发人员工具(XSRF-TOKEN 和 _csrf)中看到两个不同的 cookie,在_csrf发布后不会改变。
What I want to do is to generate a new token for each post request and check whether it's valid or not. One thing I know that I should do it for security, but I stuck.
我想要做的是为每个发布请求生成一个新令牌并检查它是否有效。我知道我应该为安全起见做一件事,但我坚持了下来。
It has been a long day and I'm new into Express and NodeJS.
这是漫长的一天,我是 Express 和 NodeJS 的新手。
Here's my current setup.
这是我目前的设置。
var express = require('express')
, passport = require('passport')
, flash = require('connect-flash')
, utils = require('./utils')
, csrf = require('csurf')
// setup route middlewares
,csrfProtection = csrf({ cookie: true })
, methodOverride = require('method-override')
, bodyParser = require("body-parser")
, parseForm = bodyParser.urlencoded({ extended: false })
, cookieParser = require('cookie-parser')
, cookieSession = require('cookie-session')
, LocalStrategy = require('passport-local').Strategy
, RememberMeStrategy = require('../..').Strategy;
var app = express();
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
app.engine('ejs', require('ejs-locals'));
app.use(express.logger());
app.use(express.static(__dirname + '/../../public'));
app.use(cookieParser());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(methodOverride());
app.use(express.session({ secret: 'keyboard cat' }));
app.use(flash());
// Initialize Passport! Also use passport.session() middleware, to support
// persistent login sessions (recommended).
app.use(passport.initialize());
app.use(passport.session());
app.use(passport.authenticate('remember-me'));
app.use(app.router);
app.use(csrf());
app.use(function (req, res, next) {
res.cookie('XSRF-TOKEN', req.csrfToken());
res.locals.csrftoken = req.csrfToken();
next();
});
Routes
路线
app.get('/form', csrfProtection, function(req, res) {
// pass the csrfToken to the view
res.render('send', { csrfToken: req.csrfToken()});
});
app.post('/process', parseForm, csrfProtection, function(req, res) {
res.send('data is being processed');
});
send.ejs (/form GET)
send.ejs (/form GET)
<form action="/process" method="POST">
<input type="hidden" name="_csrf" value="<%= csrfToken %>">
Favorite color: <input type="text" name="favoriteColor">
<button type="submit">Submit</button>
</form>
回答by Filype
Based on the amount of code you shared, a few things don't look correct:
根据您共享的代码量,有些事情看起来不正确:
1 . You may need to swap these lines so that csrf runs before the routes.
1 . 您可能需要交换这些行,以便 csrf 在路由之前运行。
app.use(app.router);
app.use(csrf());
2 . These lines need to be placed before the routes.
2 . 这些线需要放置在路线之前。
app.use(csrf());
app.use(function (req, res, next) {
res.cookie('XSRF-TOKEN', req.csrfToken());
res.locals.csrftoken = req.csrfToken();
next();
});
app.use(app.router);
3 . Use locals.csrftokenin your form
3 . locals.csrftoken在您的表单中使用
<form action="/process" method="POST">
<input type="hidden" name="_csrf" value="<%= csrftoken %>">
Favorite color: <input type="text" name="favoriteColor">
<button type="submit">Submit</button>
</form>
回答by Michael P.
the token in the cookie will be completely different than the one in the express session. you want to check for one or the other not both.
cookie 中的令牌将与快速会话中的令牌完全不同。你想检查一个或另一个而不是两个。
i would disable the cookies entirely! as it worked for me.
我会完全禁用cookies!因为它对我有用。
var csrfProtection = csurf({ cookie: false });
var csrfProtection = csurf({ cookie: false });
the author mentions it here https://github.com/expressjs/csurf/issues/52
作者在这里提到它 https://github.com/expressjs/csurf/issues/52
next you want to the "X-CSRF-Token" to the header on ajax post found here: Express.js csrf token with jQuery Ajax
接下来,您要将“X-CSRF-Token”添加到 ajax 帖子的标题中: Express.js csrf token with jQuery Ajax
回答by Laxmeesh Joshi
Below code is working for me. Let me know in case you still face issue.
下面的代码对我有用。如果您仍然遇到问题,请告诉我。
As mentioned that you wish to use cookies, you have make csurf aware that you are using cookies for setting the CSRF token.
如前所述,您希望使用 cookie,您已经让 csurf 知道您正在使用 cookie 来设置 CSRF 令牌。
Step1: Configuration
第一步:配置
var csrf = require('csurf');
var cookieparser= require('cookie-parser');
//cookieparser must be placed before csrf
app.use(bodyparser.urlencoded({extended:false}));
app.use(cookieParser('randomStringisHere222'));
app.use(csrf({cookie:{key:XSRF-TOKEN,path:'/'}}));
//add the your app routes here
app.use("/api", person);
app.use("/", home);
Step2: In the route,
Step2:在路线中,
res.render('myViewPage',{csrfTokenFromServer:req.csrfToken()});
Step3: Include a hidden field in the HTML for csrf token Example:
步骤 3:在 HTML 中为 csrf 令牌包含一个隐藏字段示例:
<form action="/api/person" method="POST">
<input type="hidden" name="_csrf" value=<%=csrfTokenFromServer %> />
First name:<br>
<input type="text" name="firstname" value="">
<br>
Last name:<br>
<input type="text" name="lastname" value="">
<br><br>
<input type="submit" value="Submit">
</form>

