admin管理员组

文章数量:1405304


I am trying to use csrf in my NodeJS application. You can see the code below. When I run this code I am getting "TypeError: req.csrfToken is not a function" error.

I want to create csrf token for all requests and want to check csrf tokens in ajax calls. As I said I can not create csrf token, I am getting error. Also how can I check csrf token in ajax calls?

Can you help me ?
Thanks

Server Side:

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

/*this line mented*/
//var csrfProtection = csrf({ cookie: false });
var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');

var parseForm = bodyParser.urlencoded({ extended: false });
app.use(cookieParser());

/*this line added*/
app.use(csrf({ cookie: false }));

app.use(session({
    genid: function (req) {
        return "lkgktktgjknvfndkj-dfgjnkdfkjgn-dfgdfg";
    },
    name: "mySecret",
    resave: false, // don't save session if unmodified
    saveUninitialized: false, // don't create session until something stored
    secret: 'thisIsASecret'
}));

app.use(express.static(path.join(__dirname, 'public')));

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

    next();
});

app.get('/', /*csrfProtection,*/ function (req, res) {
    res.render('index')
});

app.post('/process', parseForm, /*csrfProtection,*/ function (req, res) {
    res.send('data is being processed')
});

Index.jade

meta(name="csrf-token", content="#{csrfToken}")
block content
    input(type="hidden" name="_csrf" value="#{csrfToken}")

    |Favorite color: <input type="text" name="favoriteColor">
    button(type="submit" id="sbmt") Submit

    script(src= "/javascripts/jquery-2.2.1.js")

    script.
        $.ajaxPrefilter(function(options, originalOptions, jqXHR) {
          var token;
          if (!options.crossDomain) {
            token = $('meta[name="csrf-token"]').attr('content');
            if (token) {
                return jqXHR.setRequestHeader('X-CSRF-Token', token);
            }
          }
        });

        $("#sbmt").click(function (e) {
            e.preventDefault();
            $.post(
                "/process",
                {
                    //text: text,
                    _csrf : $('meta[name="csrf-token"]').attr('content')
                }, function (data) {
                    console.log(data);
                });
        });


I am trying to use csrf in my NodeJS application. You can see the code below. When I run this code I am getting "TypeError: req.csrfToken is not a function" error.

I want to create csrf token for all requests and want to check csrf tokens in ajax calls. As I said I can not create csrf token, I am getting error. Also how can I check csrf token in ajax calls?

Can you help me ?
Thanks

Server Side:

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

/*this line mented*/
//var csrfProtection = csrf({ cookie: false });
var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');

var parseForm = bodyParser.urlencoded({ extended: false });
app.use(cookieParser());

/*this line added*/
app.use(csrf({ cookie: false }));

app.use(session({
    genid: function (req) {
        return "lkgktktgjknvfndkj-dfgjnkdfkjgn-dfgdfg";
    },
    name: "mySecret",
    resave: false, // don't save session if unmodified
    saveUninitialized: false, // don't create session until something stored
    secret: 'thisIsASecret'
}));

app.use(express.static(path.join(__dirname, 'public')));

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

    next();
});

app.get('/', /*csrfProtection,*/ function (req, res) {
    res.render('index')
});

app.post('/process', parseForm, /*csrfProtection,*/ function (req, res) {
    res.send('data is being processed')
});

Index.jade

meta(name="csrf-token", content="#{csrfToken}")
block content
    input(type="hidden" name="_csrf" value="#{csrfToken}")

    |Favorite color: <input type="text" name="favoriteColor">
    button(type="submit" id="sbmt") Submit

    script(src= "/javascripts/jquery-2.2.1.js")

    script.
        $.ajaxPrefilter(function(options, originalOptions, jqXHR) {
          var token;
          if (!options.crossDomain) {
            token = $('meta[name="csrf-token"]').attr('content');
            if (token) {
                return jqXHR.setRequestHeader('X-CSRF-Token', token);
            }
          }
        });

        $("#sbmt").click(function (e) {
            e.preventDefault();
            $.post(
                "/process",
                {
                    //text: text,
                    _csrf : $('meta[name="csrf-token"]').attr('content')
                }, function (data) {
                    console.log(data);
                });
        });
Share Improve this question edited Apr 6, 2016 at 8:06 baris usanmaz asked Apr 6, 2016 at 6:12 baris usanmazbaris usanmaz 8491 gold badge15 silver badges32 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 3

You have to add:

app.use(session({ ... });
// Add this after session
app.use(csrfProtection);

You need to add this AFTER the session as stated here:

If you are setting the "cookie" option to a non-false value, then you must use cookie-parser before this module. Otherwise, you must use a session middleware before this module. For example: express-session cookie-session

Calling csrf() returns a function (source). You need to use it in order to have it. What you've missed in the tutorial is:

var csrfProtection = csrf({ cookie: true })
app.get('/form', csrfProtection, function(req, res) {
    // pass the csrfToken to the view
    res.render('send', { csrfToken: req.csrfToken() })
})

Here, the csrfProtection is actually being called, and it adds csrfToken method to req. In the other example there is:

app.use(csrf({ cookie: true }))

Which means all routes will use the protection and therefore no post without it would be possible.

It depends on your usage - if you want to secure all routes - use it globally (app.use), otherwise use it per request (as in the first example).

If you try using it in your index route you will have it, because you've used it as middleware:

app.get('/', csrfProtection, function (req, res) {
    res.render('index')
});

本文标签: javascriptUsing CSRF in NodeJSStack Overflow