我在车把each loop
上的CSRF令牌有问题。我用each loop
生成了一个数据表,但是我不能提交delete
按钮。 CSRF仅适用于提交新数据(POST)和提交更新数据(PUT)。这是我的设置:
app.js
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var expressHbs = require('express-handlebars');
var mongoose = require('mongoose');
var session = require('express-session');
var MongoStore = require('connect-mongo')(session);
var passport = require('passport');
var flash = require('connect-flash');
var validator = require('express-validator');
var override = require('method-override');
var routes = require('./routes/index');
var userRoutes = require('./routes/user');
var itemRoutes = require('./routes/item');
var app = express();
// connect to mongodb
mongoose.Promise = global.Promise;
mongoose.connect('localhost:27017/toolswatcher');
require('./config/passport');
// view engine setup
// app.set('views', path.join(__dirname, 'views'));
app.engine('.hbs', expressHbs({
defaultLayout: 'layout',
extname: '.hbs',
helpers: {
counter: function(index) {
return index + 1;
}
}
}));
app.set('view engine', 'hbs');
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(validator());
app.use(session({
secret: '234234sda',
resave: false,
saveUninitialized: false,
store: new MongoStore({
mongooseConnection: mongoose.connection
}),
cookie: { maxAge: 100 * 60 * 1000 } // minutes * seconds * milis
}));
app.use(flash());
app.use(passport.initialize());
app.use(passport.session());
app.use(override(function (req, res) {
if (req.body && typeof req.body === 'object' && '_method' in req.body) {
// look in urlencoded POST bodies and delete it
var method = req.body._method;
delete req.body._method;
return method;
}
}));
app.use(express.static(path.join(__dirname, 'public')));
[...]
路由item.js
var express = require('express');
var router = express.Router();
/*CSRF protection*/
var csrf = require('csurf');
var csrfProtection = csrf();
router.use(csrfProtection);
var Item = require('../models/item/item');
/* GET items listing */
router.get('/', isLoggedIn, function(req, res, next) {
session_store = req.user.username;
Item.find({}, function (err, item) {
if (err) return console.error(err, res);
res.render('item/index', {items: item, csrfToken: req.csrfToken()});
}).select('item_id item_name description stock image_path');
});
/* Delete item by ID*/
router.delete('/delete/:id', isLoggedIn, function (req, res, next) {
Item.findById(req.params.id, function (err, item) {
item.remove(function (err, item) {
if(err) return console.error(res, err);
console.log('DELETE removing ID: ' + item._id);
res.redirect('/item');
});
});
});
我的看法是:
<h2 class="page-header">Data Items</h2>
<div class="row">
<div class="col-md-4">
<a href="/item/add" class="btn btn-primary pull-left">
<i class="fa fa-plus" aria-hidden="true"> New Item</i>
</a>
</div>
<div class="col-md-4 col-md-offset-4">
<div class="input-group">
<input type="text" class="form-control" id="searchItem" onkeyup="searchTableItem()" placeholder="Search item name..">
<div class="input-group-addon"><span><i class="fa fa-search" aria-hidden="true"></i></span></div>
</div>
</div>
</div>
<div class="table-responsive no-padding" id="itemList">
<table class="table table-hover table-striped" id="myTable">
<thead>
<th>No.</th>
<th>Item ID</th>
<th>Item Name</th>
<th>Descriptions</th>
<th>Stock</th>
<th>Action</th>
</thead>
<tbody>
{{#each items as |item key|}}
<tr>
<td>{{ counter @key }}</td>
<td>{{ item.item_id }}</td>
<td>{{ item.item_name }}</td>
<td>{{ item.description }}</td>
<td>{{ item.stock }}</td>
<td>
<div style="display:inline-block; margin-right:5px;">
<a href="/item/details/{{item._id}}" class="btn btn-primary btn-xs">
<i class="glyphicon glyphicon-eye-open"></i>
</a>
</div>
<div style="display:inline-block; margin-right:5px;">
<a class="btn btn-success btn-xs" href="/item/edit/{{item._id}}">
<i class="glyphicon glyphicon-pencil"></i>
</a>
</div>
<div style="display:inline-block; margin-right:5px;">
<form action="/item/delete/{{item._id}}" method="post">
<input type="hidden" name="_csrf" value="{{ csrfToken }}">
<input type="hidden" name="_method" value="DELETE">
<button class="btn btn-danger btn-xs" type="submit">
<i class="glyphicon glyphicon-trash"></i>
</button>
</form>
</div>
</td>
</tr>
{{/each }}
</tbody>
</table>
</div>
我为
csrfToken
添加了隐藏的输入字段,但它不起作用,每次单击删除按钮时,它始终显示invalid csrf token
。我不知道为什么在循环内无法访问令牌,但是如果我在循环外打印csrfToken
,它会起作用,令牌会打印在页面上。 最佳答案
您的csrfToken当前正以“”传递。为了解决此问题,而不是{{csrfToken}},请输入{{../csrfToken}}。
答案编辑原因:找到更简单的解决方案。