Node Express和csurf - 403(禁止)无效的csrf令牌 [英] Node Express and csurf - 403 (Forbidden) invalid csrf token

查看:162
本文介绍了Node Express和csurf - 403(禁止)无效的csrf令牌的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

仔细观察并尝试了我在这里找到的所有东西,以及Googling在其他地方找到的东西......而我却无法超越这个。我正在使用Node,Express,EJS,并尝试在表单上使用csurf,这是使用jQuery ajax发布的。无论我如何配置csurf,我都会得到403(Forbidden)无效的csrf令牌

Looked through and tried everything I could find on here, and elsewhere by Googling...and I'm just not able to get past this. I'm using Node, Express, EJS, and attempting to use csurf on a form, that is posted w/ jQuery ajax. No matter how I configure csurf, I get "403 (Forbidden) invalid csrf token"

我尝试在app.js和控制器中全局配置。这是我在app.js中尝试的内容:

I've tried configuring both globally in app.js and in the controller. Here's what I tried in app.js:

var express = require('express');
var session  = require('express-session');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var mysql = require('mysql');
var flash = require("connect-flash");
var csrf = require("csurf");

var app = express();

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

app.use(logger('dev'));
app.use(cookieParser());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));
app.use(session({
    secret: 'somethingsecret',
    resave: true,
    saveUninitialized: true,
    httpOnly: true,
    secure: false
}));
app.use(csrf());
app.use(function (req, res, next) {
    var token = req.csrfToken();
    res.cookie('XSRF-TOKEN', token);
    res.locals.csrfToken = token;
    console.log("csrf token = " + token);
    next();
});
app.use(flash());
app.use(express.static(path.join(__dirname, 'public')));

app.use(function (err, req, res, next) {
    if (err.code !== 'EBADCSRFTOKEN') return next(err);

    // handle CSRF token errors here
    res.status(403);
    res.send('form tampered with');
})

//routing
var routes = require('./routes/index');
var users = require('./routes/users');
var register = require('./routes/register');

app.use('/', routes);
app.use('/users', users);
app.use('/register', register);

...使用此控制器:

...with this controller:

var express = require("express");
var router = express.Router();
var bodyParser = require("body-parser");
var userSvc = require("../service/userservice");

var jsonParser = bodyParser.json();

router.get("/", function(req, res, next) {
    console.log("token = " + token);
    userSvc.getAllPublicRoles(function(data) {
        res.render("register", {
            title: "Register a new account",
            roles: data
        });
    });
});

router.post("/new", jsonParser, function(req, res, next) {
    userSvc.addUser(req.body, function(result) {
        console.log("New user id = " + result.insertId);
        res.send('{"success" : "Updated Successfully", "status" : 200}');
    });
});

...并且此观点:

form:

<form id="registerForm" class="form-horizontal" method="post">
    <input type="hidden" name="_csrf" value="<%= csrfToken %>" />

ajax电话:

        $.ajax({
            url: "/register/new",
            type: "POST",
            dataType: "json",
            data: user
        }).done(function(data) {
            if (data) {
                console.log("Success! = " + data);
            }
        }).fail(function(data) {
            console.log("Something went wrong: " + data.responseText);
        });

然后我只是尝试在控制器中执行所有操作,从app中删除所有引用,调用等.js,并使用与上述相同的形式和ajax调用:

Then I just tried just doing everything in the controller, removing all references, calls, etc. from app.js, and using the same form and ajax call as above:

var express = require("express");
var router = express.Router();
var bodyParser = require("body-parser");
var csrf = require("csurf");
var userSvc = require("../service/userservice");

var csrfProtection = csrf();
var jsonParser = bodyParser.json();

router.get("/", csrfProtection, function(req, res, next) {
    var token = req.csrfToken();
    console.log("token = " + token);
    userSvc.getAllPublicRoles(function(data) {
        res.render("register", {
            title: "Register a new account",
            csrfToken: token,
            roles: data
        });
    });
});

router.post("/new", jsonParser, csrfProtection, function(req, res, next) {
    userSvc.addUser(req.body, function(result) {
        console.log("New user id = " + result.insertId);
        res.send('{"success" : "Updated Successfully", "status" : 200}');
    });
});

不确定从何处开始。我一直在使用节点大约两个星期,在我的业余时间,所以请原谅我的无知。

Not sure where to go from here. I've been using node for about two weeks, in my spare time, so pardon my ignorance here.

推荐答案

如果你想要要将令牌存储在cookie而不是会话中,让csurf为您创建cookie,例如

If you want to store the token in a cookie instead of the session, let csurf create the cookie for you e.g.

// Store the token in a cookie called '_csrf'
app.use(csrf({cookie: true));

// Make the token available to all views
app.use(function (req, res, next){
    res.locals._csrf = req.csrfToken();
    next();
});

然后,您需要确保在使用AJAX进行呼叫时令牌可用POST的数据,或者作为自定义请求标题,例如'xsrf-token'。

Then you need to make sure the token is available when you're making the call using AJAX either via the POST'ed data, or as a custom request header such as 'xsrf-token'.

此时,您正在向表单提供令牌,但是不是实际的请求(使用AJAX发送)。

At the minute, you're providing the token to the form, but not the actual request (sent using AJAX).

例如,您可以在AJAX设置中呈现令牌:

For example, you could render the token in the AJAX setup:

$.ajaxSetup({
   headers: {"X-CSRF-Token": "{{csrfToken}}" }
}); 

这篇关于Node Express和csurf - 403(禁止)无效的csrf令牌的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆