NodeJS 快速CSRF令牌验证

zpf6vheq  于 2023-02-18  发布在  Node.js
关注(0)|答案(4)|浏览(178)

我遇到了CSRF令牌的问题。当我提交一个表单时,一个新的XSRF-TOKEN被生成,但我认为我生成了两个不同的令牌,我有点困惑。还有一个名为_csrf的令牌,所以我在开发者工具中看到了两个不同的cookie(XSRF-TOKEN和_csrf),_csrf在发布后没有改变。
我想做的是为每个post请求生成一个新的token,并检查它是否有效。我知道为了安全起见我应该这样做,但我坚持了下来。
这是漫长的一天,我是新进入快递和NodeJS。
这是我目前的设置。

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();
});

路线

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');
});

发送.ejs(/表单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>
ymzxtsji

ymzxtsji1#

根据您共享的代码量,我将提到一些在我看来不太正确的事情:
1 .您可能需要交换下面的行,以便csrf在路由之前运行。

app.use(csrf());
app.use(app.router);

2 .还需要将csrftoken设置置于路由之前。

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 .您需要在表单中使用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>
3npbholx

3npbholx2#

这标记在这cookie将是完全不同的到这一个在这express对话.你想要到检查为一个或那不是这两者.
我会完全禁用cookie!因为它对我有效。
var csrf保护= csurf({cookie:错误});
作者在这里提到https://github.com/expressjs/csurf/issues/52
接下来,您需要将"X-CSRF-Token"添加到ajax帖子的标题中,可以在此处找到:Express.js csrf token with jQuery Ajax

w9apscun

w9apscun3#

下面的代码是为我工作。让我知道,如果你仍然面临问题。
如前所述,您希望使用Cookie,您必须让csurf知道您正在使用Cookie来设置CSRF令牌。
步骤1:配置

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:在路由中,

res.render('myViewPage',{csrfTokenFromServer:req.csrfToken()});

步骤3:在csrf标记的HTML中包含隐藏字段示例:

<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>
8zzbczxx

8zzbczxx4#

当我们设置csrf cookie的时候,它有默认键'_csrf'。我们可以覆盖它。所以在我的例子中,我给cookie取了相同的名字。

const csrf = csurf({cookie:{key:'XSRF-TOKEN'}});

app.get('/csrf-token',csrf,(req:Request,res:Response,next:NextFunction)=>{

    const newToken = req.csrfToken();

    res.cookie('XSRF-TOKEN', newToken, {
      httpOnly: true,
      sameSite: 'strict',
      secure: process.env.NODE_ENV === 'production',
    });

    res.json({ csrfToken: newToken });

});
我不知道你是否解决了这个问题,但它仍然会帮助,如果别人寻找它。

相关问题