2015-08-08 12 views
2

Я пытался заставить csurf работать, но, похоже, что-то наткнулся на что-то. Код до сих пор выглядит следующим образом:ForbiddenError: недействительный токен csrf, express js

index.ejs

<form method="post" action="/"> 
      <input type="hidden" name="_csrf" value="{{csrfToken}}"> 
      . 
      . 
</form> 

Где вы вводите пароль и имя пользователя в форме.

app.js

var express = require('express'); 
var helmet = require('helmet'); 
var csrf = require('csurf'); 
var path = require('path'); 
var favicon = require('serve-favicon'); 
var flash = require('connect-flash'); 
var logger = require('morgan'); 
var cookieParser = require('cookie-parser'); 
var bodyParser = require('body-parser'); 
var session = require('express-session'); 


var routes = require('./routes/index'); 
var users = require('./routes/users'); 
var profile = require('./routes/profile'); 

var app = express(); 


// view engine setup 
app.set('views', path.join(__dirname, 'views')); 
app.set('view engine', 'ejs'); 

// uncomment after placing your favicon in /public 
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico'))); 

app.use(logger('dev')); 

//Security shyts 

app.use(helmet()); 
app.use(helmet.xssFilter({ setOnOldIE: true })); 
app.use(helmet.frameguard('deny')); 
app.use(helmet.hsts({maxAge: 7776000000, includeSubdomains: true})); 
app.use(helmet.hidePoweredBy()); 
app.use(helmet.ieNoOpen()); 
app.use(helmet.noSniff()); 
app.use(helmet.noCache()); 

// rest of USE 
app.use(logger('dev')); 
app.use(bodyParser.json()); 
app.use(bodyParser.urlencoded({ extended: false })); 
app.use(cookieParser()); 
app.use(session({secret: 'anystringoftext', saveUninitialized: true, resave: true, httpOnly: true, secure: true})); 
app.use(csrf()); // Security, has to be after cookie and session. 
app.use(flash()); 
app.use(express.static(path.join(__dirname, 'public'))); 
app.use('/', routes); 
app.use('/users', users); 
app.use('/profile', profile); 


// catch 404 and forward to error handler 

app.use(function (req, res, next) { 
    res.cookie('XSRF-TOKEN', req.csrfToken()); 
    res.locals.csrftoken = req.csrfToken(); 
    next(); 
}) 

//app.use(function(req, res, next) { 
// var err = new Error('Not Found'); 
// err.status = 404; 
// next(err); 
//}); 

// error handlers 

// development error handler 
// will print stacktrace 
if (app.get('env') === 'development') { 
    app.use(function(err, req, res, next) { 
    res.status(err.status || 500); 
    res.render('error', { 
     message: err.message, 
     error: err 
    }); 
    }); 
} 

// production error handler 
// no stacktraces leaked to user 
app.use(function(err, req, res, next) { 
    res.status(err.status || 500); 
    res.render('error', { 
    message: err.message, 
    error: {} 
    }); 
}); 


module.exports = app; 

Где я положил CSRF после сессии и куки синтаксического анализа.

index.js

/* GET home page. */ 
router.get('/', function(req, res, next) { 
    res.render('index', { title: 'some title',message: '' }); 
}); 

router.post('/',function(req,res){ 
// Where I have a bunch of mysql queries to check passwords and usernames where as if they succeed they get: 
res.redirect('profile'); 
// Else: 
res.redirect('/'); 
}); 

Что я получаю после завершения заполнения формы, независимо от того, если я ввожу правильное имя пользователя и пароль или нет, я все еще получаю ту же ошибку:

invalid csrf token 

403 

ForbiddenError: invalid csrf token 

Также я хочу добавить, что я работал с узлом около 2 недель, поэтому мне все еще нужно учиться, вероятно.

+0

Проводятся ли ваши маршруты до или после промежуточного ПО csurf? Это поможет, если вы продемонстрируете полный код ... – James

+0

Угадайте, что я смог распечатать всю часть app.js. Готово! – Drwk

+0

Глупый вопрос, но вы определенно привязываете токен к форме? Я не вижу, что это происходит в вашем примере. – James

ответ

5

{{csrfToken}} не является конструкцией EJS, поэтому он не расширен вообще и, вероятно, отправлен буквально на ваш сервер.

Это должно работать лучше:

<input type="hidden" name="_csrf" value="<%= csrfToken %>"> 

Промежуточное устанавливает csrftoken хотя, с строчной 'т', где шаблон ожидает заглавная 'T':

res.locals.csrftoken = req.csrfToken(); // change to `res.locals.csrfToken` 

Вы также генерировать два разные тонеры, которые, вероятно, не то, что вы хотите:

app.use(function (req, res, next) { 
    var token = req.csrfToken(); 
    res.cookie('XSRF-TOKEN', token); 
    res.locals.csrfToken = token; 
    next(); 
}); 

И наконец, вам, вероятно, придется переместить свое промежуточное программное обеспечение до объявлений маршрута, иначе оно не будет называться:

app.use(function (req, res, next) { 
    var token = req.csrfToken(); 
    res.cookie('XSRF-TOKEN', token); 
    res.locals.csrfToken = token; 
    next(); 
}); 
app.use('/', routes); 
app.use('/users', users); 
app.use('/profile', profile); 
+0

Я попробую и отчитаю! – Drwk

+0

Нет ошибок и все сработало! Я продолжу и прочитаю более подробную информацию о том, как передаются токены и так далее. Я, однако, кланяюсь и чем ты! – Drwk

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