javascript - Node Express 和 csurf - 403(禁止)无效的 csrf token

标签 javascript jquery ajax node.js express

通过谷歌搜索浏览并尝试了我在这里和其他地方可以找到的所有内容……但我就是无法克服这个问题。我正在使用 Node、Express、EJS,并尝试在使用 jQuery ajax 发布的表单上使用 csurf。无论我如何配置 csurf,我都会收到“403(禁止)无效的 csrf token ”

我已经尝试在 app.js 和 Controller 中进行全局配置。这是我在 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);

...使用这个 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}');
    });
});

...以及这个 View :

形式:

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

然后我只是尝试在 Controller 中做所有事情,从 app.js 中删除所有引用、调用等,并使用与上面相同的表单和 ajax 调用:

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

不知道从这里去哪里。我在业余时间使用 node 大约两周了,所以请原谅我的无知。

最佳答案

如果您想将 token 存储在 cookie 而不是 session 中,让 csurf 为您创建 cookie,例如

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

然后,当您通过 POST 数据或作为自定义请求 header (例如“xsrf-token”)使用 AJAX 进行调用时,您需要确保 token 可用。

此刻,您正在向表单提供 token ,而不是实际请求(使用 AJAX 发送)。

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

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

关于javascript - Node Express 和 csurf - 403(禁止)无效的 csrf token ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33849252/

相关文章:

javascript - 博客/消息 - 如何解决空消息 div 相互堆叠/相邻并使关闭按钮起作用的问题?

javascript - AJAX:在 readyState = 1 时停止运行

javascript - 下拉自动完成

javascript - 当我控制台日志时,我得到 "w.fn.init [prevObject: w.fn.init(1)]"

javascript - 将下拉选择的值传递给 JavaScript 中的 URL,以打开 anchor 标记窗口

javascript - 在新数组项上附加 ajax 中的 PHP 数组项

jQuery。表中每一行的 Ajax 请求

javascript - 在 GWT 应用程序中停止 Gflot 自动注入(inject) Jquery/javascript

javascript - 使用 D3.js 制作旭日图

javascript - 在保留范围链的同时将回调函数作为字符串传递