2017-03-02 8 views
1

Handlebars each loopのCSRFトークンに問題があります。 each loopのデータテーブルを生成しましたが、deleteボタンを送信できません。 CSRFは、新しいデータの送信(POST)と更新データ(PUT)の送信にのみ機能します。ここに私のセットアップは次のとおりです。私が追加したExpress表のアクション内の無効なCSRFトークンボタン

<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">&nbsp;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> 

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

そして、私のビューの非表示の入力フィールドそれは動作しません、それは常にinvalid csrf token私は削除ボタンをクリックするたびに表示されます。トークンがループ内でアクセスできない理由はわかりませんが、ループの外側にcsrfTokenを印刷すると、トークンがページに表示されます。

+0

私は同じ問題があります:( –

答えて

0

あなたのcsrfTokenは現在 "...."として渡されています。 {{csrfToken}}の代わりにこれを修正するには{{.. ../csrfToken}}と入力してください。

回答済み編集理由:簡単な解決策が見つかりました。

関連する問題