2014-12-04 1 views
0

Я работаю над книгой Этана Брауна «Веб-разработка с узлом и экспрессом», и все прошло хорошо, пока я не получил возможность запускать csrf при загрузке многостраничных/формальных данных на фото загрузить. Я скачал полную книгу код из Github, https://github.com/EthanRBrown/web-development-with-node-and-express и что делает то же самое, работает до тех пор, CSRF не включен, то это ошибки с:Эксплуатация Express4 и загружаемая загрузка файлов до тех пор, пока я не включу csrf

Ошибки: недопустимый CSRF токена

здесь биты коды, я думаю, актуальны , /meadowlark.js начиная с линии 100

app.use(require('cookie-parser')(credentials.cookieSecret)); 
app.use(require('express-session')({ store: sessionStore, 
      secret: credentials.cookieSecret, 
      name: credentials.cookieName, 
      saveUninitialized: true, 
      resave: true })); 
app.use(express.static(__dirname + '/public')); 
app.use(require('body-parser')()); 

// cross-site request forgery protection 
app.use(require('csurf')()); 
app.use(function(req, res, next){ 
    res.locals._csrfToken = req.csrfToken(); 
    next(); 
}); 

// database configuration 
var mongoose = require('mongoose'); 
var options = { 
    server: { 
     socketOptions: { keepAlive: 1 } 
    } 
}; 

Тогда в /handlers/contest.js

var path = require('path'), 
    fs = require('fs'), 
    formidable = require('formidable'); 

// make sure data directory exists 
var dataDir = path.normalize(path.join(__dirname, '..', 'data')); 
var vacationPhotoDir = path.join(dataDir, 'vacation-photo'); 
fs.existsSync(dataDir) || fs.mkdirSync(dataDir); 
fs.existsSync(vacationPhotoDir) || fs.mkdirSync(vacationPhotoDir); 

exports.vacationPhoto = function(req, res){ 
    var now = new Date(); 
    res.render('contest/vacation-photo', { year: now.getFullYear(), month: now.getMonth() }); 
}; 

function saveContestEntry(contestName, email, year, month, photoPath){ 
    // TODO...this will come later 
} 

exports.vacationPhotoProcessPost = function(req, res){ 
    var form = new formidable.IncomingForm(); 
    form.parse(req, function(err, fields, files){ 
     if(err) return res.redirect(303, '/error'); 
     if(err) { 
      res.session.flash = { 
       type: 'danger', 
       intro: 'Oops!', 
       message: 'There was an error processing your submission. ' + 
        'Pelase try again.', 
      }; 
      return res.redirect(303, '/contest/vacation-photo'); 
     } 
     var photo = files.photo; 
     var dir = vacationPhotoDir + '/' + Date.now(); 
     var path = dir + '/' + photo.name; 
     fs.mkdirSync(dir); 
     fs.renameSync(photo.path, dir + '/' + photo.name); 
     saveContestEntry('vacation-photo', fields.email, 
      req.params.year, req.params.month, path); 
     req.session.flash = { 
      type: 'success', 
      intro: 'Good luck!', 
      message: 'You have been entered into the contest.', 
     }; 
     return res.redirect(303, '/contest/vacation-photo/entries'); 
    }); 
}; 

exports.vacationPhotoEntries = function(req, res){ 
    res.render('contest/vacation-photo/entries'); 
}; 

и просмотров/конкурс/отпуск-photo.handleba rs

<form class="form-horizontal" role="form" 
     enctype="multipart/form-data" method="POST" 
     action="/contest/vacation-photo/{{year}}/{{month}}"> 
    <input type="hidden" name="_csrf" value="{{_csrfToken}}"> 
    <div class="form-group"> 
     <label for="fieldName" class="col-sm-2 control-label">Name</label> 
     <div class="col-sm-4"> 
      <input type="text" class="form-control" 
      id="fieldName" name="name"> 
     </div> 
    </div> 
    <div class="form-group"> 
     <label for="fieldEmail" class="col-sm-2 control-label">Email</label> 
     <div class="col-sm-4"> 
      <input type="email" class="form-control" required 
       id="fieldName" name="email"> 
     </div> 
    </div> 
    <div class="form-group"> 
     <label for="fieldPhoto" class="col-sm-2 control-label">Vacation photo</label> 
     <div class="col-sm-4"> 
      <input type="file" class="form-control" required accept="image/*" 
       id="fieldPhoto" data-url="/upload" name="photo"> 
     </div> 
    </div> 
    <div class="form-group"> 
     <div class="col-sm-offset-2 col-sm-4"> 
      <button type="submit" class="btn btn-primary">Submit</button> 
     </div> 
    </div> 
</form> 

Каков правильный способ сделать работу csrf?

Спасибо,

ответ

1

По запросу каникул фото GET, вы должны отправить CSRF токен, как показано ниже.

exports.vacationPhotoEntries = function(req, res){ 
    res.render('contest/vacation-photo/entries', { _csrfToken: req.csrfToken()}); 
}; 

Вы также можете поймать CSRF лексемы ошибка в обработчике ошибок по умолчанию, как показано ниже.

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

// handle CSRF token errors here 
res.status(403) 
res.send('session has expired or form tampered with') 
}) 

Для получения дополнительной информации, пожалуйста, проверьте this link.

0

Добавить токен csrf как строку запроса в действие Url .. Он работает!

+0

С благодарностью Ходжин, я забыл все об этой проблеме, и поскольку мое приложение является внутренним, я просто переместил этот маршрут до промежуточного ПО CSRF, пока я не вернусь и не исправлю его. Ваше решение работает. Глядя на это сейчас, кажется, так просто, я думаю, что в то время моя голова была не в нужном месте. Я бы ответил, но у меня недостаточно очков репутации. – HyperSprite

Смежные вопросы