Node Express和csurf-403(禁止)无效的csrf令牌
Node Express and csurf - 403 (Forbidden) invalid csrf token
浏览并尝试了我在这里和其他地方通过谷歌找到的一切。。。而我就是无法度过这一关。我正在使用Node、Express、EJS,并尝试在表单上使用csurf,该表单是通过/jQueryajax发布的。无论我如何配置csurf,我都会得到"403(禁止)无效csrf令牌"
我已经尝试在app.js和控制器中进行全局配置。以下是我在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);
使用此控制器:
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 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调用:
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大约两周了,所以请原谅我的无知。
如果您想将令牌存储在cookie中而不是会话中,请让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();
});
然后,当您使用AJAX进行调用时,您需要确保令牌是可用的,无论是通过POST’ed数据,还是作为自定义请求头(如"xsrf令牌")。
目前,您正在向表单提供令牌,而不是实际的请求(使用AJAX发送)。
例如,您可以在AJAX设置中呈现令牌:
$.ajaxSetup({
headers: {"X-CSRF-Token": "{{csrfToken}}" }
});
经过几个小时的故障排除和搜索,我找到了一篇帮助回答问题的帖子。我只需要在ajax帖子中传递标题值。有道理,我只是忽略了它。就像这样:
<input type="hidden" id="_csrf" name="_csrf" value="<%= csrfToken %>" />
然后在jQuery:中
$.ajaxSetup({
headers: {"X-CSRF-Token": $("#_csrf").val()}
});
我个人项目的另一种方法是在我成功提交表单时重新发送一个新令牌:
例如,在我的表单(进行文件上传)上,我有以下html:
<form id="upload_form" type="multipart/form-data" data-csrf="{{csrfToken}}" method="post" action="/data_assets">
<input id="excell_upload" type="file" style="visible:hidden" name="data_assets"/>
</form>
在文件更改时,我会触发这样的上传:
$('#excell_upload').on('change',function(event){
event.preventDefault();
var formData = new FormData($("#upload_form")[0]);
$.ajax({
'type':$("#upload_form").attr('method'),
'data': formData,
'url': $("#upload_form").attr('action'),
'processData': false,
'contentType': false,
'mimeType': 'multipart/form-data',
'headers': {"X-CSRF-Token": $("#upload_form").attr('data-csrf') },
'beforeSend': function (x) {
if (x && x.overrideMimeType) {
x.overrideMimeType("multipart/form-data");
}
$('#trigger_upload').addClass('disabled');
},
'success':function(data){
$('#upload_form').attr('data-csrf',data.csrfToken)
},
'fail':function(){
},
'complete':function(){
$('#trigger_upload').removeClass('disabled');
}
});
});
正如您所注意到的,我收到了一个新的csrf令牌,以便能够重新使用我的表单进行新的提交。我像这样重新生成CSRF令牌:
app.post('/data_assets',function(req,res,next){
res.json({'csrfToken':req.csrfToken()});
});
除了在帖子的标题中添加"X-CSRF-Token"之外,你还想完全禁用cookie!
var csrfProtection=csurf({cookie:false});
作者在这里提到https://github.com/expressjs/csurf/issues/52
cookie和会话验证不应该结合在一起——尽管这有点误导,因为他在文档中结合了cookie和会话的验证:https://github.com/expressjs/csurf#simple-表示示例
- 如果我在javascript中输入无效的电子邮件或空白,如何显示特定的文本框边框红色
- jquery代码在Mozilla中有效,但在其他浏览器上无效
- Django: AJAX + CSRF POST gives 403
- 这个问号在Flow中意味着什么:“;?()=>“无效”;
- 从字符串末尾删除空白无效
- Jquery Datatables错误:无效的JSON基元:draw
- 滚动在Chrome中有效,但在Firefox或IE中无效
- 错误:语法错误,无法识别的表达式:不支持的伪:无效/RectJS/Unit Testing
- Javascript setattribute-名称和值无效
- 如何照顾CSRF&单页应用程序中不使用cookie的XSS攻击
- 格式化货币无效
- JavaScript错误无效的限定符
- 按键事件无效的原因
- Laravel数据表无效的JSON响应
- 文本字段显示它是有效的,即使它在ExtJS中是无效的
- Symfony2 动态表单修改 ajax jquery 无效的 CSRF 令牌
- Node Express和csurf-403(禁止)无效的csrf令牌
- 无法摆脱ForbiddenError:无效的csrf令牌在express与csurf
- Node.js csurf无效CSRF令牌
- ForbiddenError:无效的csrf令牌,表示js