CSRF 403禁止 – 无效的CSRF令牌

我遇到了Node Express和CSurf的问题 – 403(Forbidden)csrf令牌无效。 通过其他的答案看,并试图find一切,我可以通过searchfind,我只是无法克服这一点。

我在邮递员testing了API,它工作得很好。

当我尝试在login表单上使用它时,它不起作用。

后端代码:

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 session = require('client-sessions'); var session = require('express-session'); var flash = require('connect-flash'); var csrf = require('csurf'); var cors = require('cors'); //======== newly added ===== // var csrfProtection = csrf({ cookie: true }); //==== end of all ========== // var RedisStore = require('connect-redis')(session); // var fileUpload = require('express-fileupload'); var app = express(); // app.use(fileUpload()); // 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')); app.use(bodyParser.json()); app.use(bodyParser.json({limit: '100mb'})); app.use(bodyParser.urlencoded({limit: '100mb', extended: true, parameterLimit:50000})); app.use(cors()); app.options('*', cors()); app.use(cookieParser()); app.set('trust proxy', 1) // trust first proxy app.use(session({ secret : 'irutirutiurtuiru', expires : new Date(Date.now() + 3600000), resave : false, saveUninitialized : true, })); app.use(flash()); //To disable x-powered-by details in header app.disable('x-powered-by'); app.use(csrf({ cookie: true })); var index = require('./routes/index'); var users = require('./routes/users'); var tags = require('./routes/tags'); var access = require('./routes/access'); var brand = require('./routes/brand'); var user = require('./routes/user'); var article = require('./routes/article'); var articlenew = require('./routes/articlenew'); // var imageUpload = require('./routes/imageUpload'); var faq = require('./routes/faq'); var login = require('./routes/login'); var admin = require('./routes/admins'); var editorpick = require('./routes/editorpick'); var log = require('./routes/log'); var articleadminview = require('./routes/articleadminview'); var logout = require('./routes/logout'); var domain = require('./routes/domain'); var banner = require('./routes/banner'); var bannerview = require('./routes/bannerview'); var moderater = require('./routes/moderater'); var poll = require('./routes/poll'); var articleviewcount = require('./routes/articleviewcount'); var report = require('./routes/report'); var whitepaper = require('./routes/whitepaper'); var changepassword = require('./routes/changepassword'); var editprofile = require('./routes/editprofile'); app.use(require('stylus').middleware(path.join(__dirname, 'public'))); app.use(express.static(path.join(__dirname, 'public'))); app.use('/', index); // app.use('/users', users); app.use('/tags',tags); app.use('/access', access); app.use('/brand', brand); app.use('/user', user); app.use('/article', article); app.use('/articlenew', articlenew); // app.use('/imageUpload', imageUpload); app.use('/faq', faq); app.use('/login', login); app.use('/admins', admin); app.use('/editorpick', editorpick); app.use('/log', log); app.use('/articleadminview', articleadminview); app.use('/logout', logout); app.use('/domain', domain); app.use('/banner', banner); app.use('/bannerview', bannerview); app.use('/moderater', moderater); app.use('/poll', poll); app.use('/articleviewcount',articleviewcount); app.use('/report', report); app.use('/whitepaper', whitepaper); app.use('/changepassword', changepassword); app.use('/editprofile', editprofile); //client session // app.use(session({ // cookieName: 'session', // secret: 'random_string_goes_here', // duration: 30 * 60 * 1000, // activeDuration: 5 * 60 * 1000, // })); // app.use(session({ // secret: 'fnss0893oin$(@&', // resave: false, // saveUninitialized: true // })); // catch 404 and forward to error handler app.use(function(req, res, next) { // res.header("Access-Control-Allow-Origin", "*"); // res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); var err = new Error('Not Found'); err.status = 404; next(err); }); // error handler app.use(function(err, req, res, next) { // set locals, only providing error in development res.locals.message = err.message; res.locals.error = req.app.get('env') === 'development' ? err : {}; res.locals._csrf = req.csrfToken(); // if(err.code == 'EBADCSRFTOKEN'){ // res.render('csrfError'); // } // render the error page res.status(err.status || 500); // res.render('404'); res.render('error'); }); module.exports = app; 

前端代码:

 $(function(){ loginPage(); }); function loginPage(){ $('#footer').load('footer', function(){ $('.footer').addClass('posAbs'); }); $('.preloader').fadeOut(); $(document).on('click', '#signin', function() { //Retreving the input values login(); }); $( "#loginpass" ).on( "keydown", function(event) { if(event.which == 13){ login(); } }); $('.forgot-btn').on('click', function(){ $(".loginContainer").fadeOut(400, function(){ $(".resetContainer").fadeIn(400); }); }); $('.resetpass-btn').on('click', function(){ forgotPass(); }); $( ".emailId" ).on( "keydown", function(event) { if(event.which == 13){ forgotPass(); } }); $('.notifycontent, .submitted').hide(); $('.notifya').on('click', function(){ $('.notifyMain').hide(); $('.notifycontent').show(); }) $(document).on('click', '.notifysubmit', function(){ var email = $('#notifyEmail').val(); if(email == ""){ var h = $('#notifyEmail').parent().find('.highlighter'); h.show(); h.addClass('shake animated'); $('#notifyEmail').addClass('error'); h.one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function() { $(this).removeClass("shake animated"); setTimeout(function() { h.fadeOut(300); }, 5000); }); return false; } else if(email != ""){ var expr = /^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$/; if(!expr.test(email)){ var h = $('#notifyEmail').parent().find('.highlighter'); h.show().html('Enter a valid Email'); h.addClass('shake animated'); $('#notifyEmail').addClass('error'); h.one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function() { $(this).removeClass("shake animated"); setTimeout(function() { h.fadeOut(300); }, 5000); }); return false; } else{ mailAdmin(email); $('#notifyadmin').modal('hide'); } } }); inputValidate(); } function loginerror() { var email = $('.email').val(); var password = $('.password').val(); if(email == ''){ var h = $('.email').parent().find('.highlighter'); h.show(); h.addClass('shake animated'); $('.email').addClass('error'); h.one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function() { $(this).removeClass("shake animated"); setTimeout(function() { h.fadeOut(300); }, 5000); }); } else if(password == ''){ var h = $('.password').parent().find('.highlighter'); h.show(); h.addClass('shake animated'); $('.password').addClass('error'); h.one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function() { $(this).removeClass("shake animated"); setTimeout(function() { h.fadeOut(300); }, 5000); }); } } function forgotPass(){ var emailId = $('.emailId').val(); var emailRegex = new RegExp(/^([\w\.\-]+)@([\w\-]+)((\.(\w){2,3})+)$/i); var valid = emailRegex.test(emailId); if (!valid) { var h = $('.emailId').parent().find('.highlighter'); h.show(); h.addClass('shake animated'); $('.emailId').addClass('error'); h.one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function() { $(this).removeClass("shake animated"); setTimeout(function() { h.fadeOut(300); }, 5000); }); return false; } else{ $('.preloader').fadeIn(300); forgotPassword(emailId); } } function forgotPassword(email){ var settings = { "url": base_url+"/forgotpassword/"+email, "method": "GET", "async" : true, }; $.ajax(settings).done(function(data) { if (data.status === true) { $('#resetPass h4').html('Your password reset link has been mailed to '+email); $('.preloader').fadeOut(300); $('#resetPass').modal('show'); pageCheck = "reset" } else { checkactiveUser(email, pageCheck); } }).fail(function(jqXHR, textStatus, errorThrown) { if (jqXHR.status == 403 || jqXHR.status == 405) { console.log('Server error. ' + jqXHR.status + '. ' + textStatus + '. ' + errorThrown); forgotPassword(); } console.log('Server error. Please try again.'); }); } function login(){ var email = $('.email').val(); var password = $('.password').val(); var csrfToken = fetchtoken(); pageCheck = "login" if ((email != '') && (password != '')) { var settings = { "url": base_url+"/login", "method": "POST", dataType: 'json', // headers: { // "x-CSRF-token": csrfToken, // }, data:{ "email": email, "password": password, // "_csrf": csrfToken }, crossdomain : true }; $.ajax(settings).done(function(data) { if (data.status === true) { alert(); // var data = data.data; // token = data.accesstoken; // var userId = data.id; // localStorage.setItem('userId', userId); // localStorage.setItem('token', token); // var userInfo = JSON.stringify(data); // localStorage.setItem('pollVisited', data.pollVisitedFlag); // window.open('home', '_self'); } else { if(data.msg == "Email id doesnt exist"){ $('#loginError').modal('show'); } else{ $('.preloader').fadeIn(); checkactiveUser(email, pageCheck); // var h = $('.password').parent().find('.highlighter'); // h.show().html('Enter a valid password'); // h.addClass('shake animated'); // $('.password').addClass('error'); // h.one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function() { // $(this).removeClass("shake animated"); // setTimeout(function() { // h.fadeOut(300); // }, 5000); // }); } } }).fail(function(jqXHR, textStatus, errorThrown) { if (jqXHR.status == 403 || jqXHR.status == 405 || jqXHR.status == 502) { console.log('Server error. ' + jqXHR.status + '. ' + textStatus + '. ' + errorThrown); loginPage(); } console.log(jqXHR.status + textStatus + errorThrown); }); } else { loginerror(); } } function inputValidate(){ $('input').focus(function(){ $(this).removeClass('error'); $('.highlighter').fadeOut(300); }); } function logintimeLog(token){ var settings = { "url": base_url+"/logintimelog/"+ token, "method": "GET", }; $.ajax(settings).done(function(data) { if (data.status === true) { console.log('log in'); } else { console.log('Response status is false'); logintimeLog(); } }).fail(function(jqXHR, textStatus, errorThrown) { if (jqXHR.status == 403 || jqXHR.status == 405 || jqXHR.status == 502) { console.log('Server error. ' + jqXHR.status + '. ' + textStatus + '. ' + errorThrown); logintimeLog(); } console.log('Server error. Please try again.'); logintimeLog(); }); } function checkactiveUser(email, x){ var settings = { "url": base_url+"/userexist", "method": "POST", data:{ "email": email, } }; $.ajax(settings).done(function(data) { if (data.status === true) { if(data.active === 0){ $('.verify-btn').attr('disabled', true).removeClass('green').addClass('disabled'); $('#onboarding h4').html('Your account is verified.'); $('#onboarding p').html('Complete your sign-up to start using RMA.'); $('#onboarding .sign-here').hide(); $('#onboarding .black-filled').html('Okay'); $('#onboarding').modal('show'); $('.preloader').fadeOut(300); } else{ if(x == 'login'){ $('.preloader').fadeOut(300); var h = $('.password').parent().find('.highlighter'); h.show().html('Enter a valid password'); h.addClass('shake animated'); $('.password').addClass('error'); h.one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function() { $(this).removeClass("shake animated"); setTimeout(function() { h.fadeOut(300); }, 5000); }); } else{ $('.preloader').fadeOut(300); $('#onboarding').modal('show'); } } } else{ if(x == "reset"){ $('#notifyadmin').modal('show'); } if(x == 'login'){ var h = $('.password').parent().find('.highlighter'); h.show().html('Enter a valid password'); h.addClass('shake animated'); $('.password').addClass('error'); h.one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function() { $(this).removeClass("shake animated"); setTimeout(function() { h.fadeOut(300); }, 5000); }); } } }).fail(function(jqXHR, textStatus, errorThrown) { if (jqXHR.status == 403 || jqXHR.status == 405) { console.log('Server error. ' + jqXHR.status + '. ' + textStatus + '. ' + errorThrown); emailVerification(); } console.log('Server error. Please try again.'); }); } function mailAdmin(email){ $('.preloader').fadeIn(); var settings = { "url": base_url+"/mailtoadmin", "method": "POST", data:{ "email": email, } }; $.ajax(settings).done(function(data) { if (data.status === true) { $('.notifycontent').hide(); $('.submitted').show(); $('#notifyadmin').modal('show'); $('.preloader').fadeOut(); } }).fail(function(jqXHR, textStatus, errorThrown) { if (jqXHR.status == 403 || jqXHR.status == 405) { console.log('Server error. ' + jqXHR.status + '. ' + textStatus + '. ' + errorThrown); emailVerification(); } console.log('Server error. Please try again.'); }); } function fetchtoken(){ var settings = { "url": base_url+"/fetchtoken", "method": "GET", }; $.ajax(settings).done(function(data) { $('input[name="_csrf"]').val(data.token); return data.token; }).fail(function(jqXHR, textStatus, errorThrown) { if (jqXHR.status == 403 || jqXHR.status == 405) { console.log('Server error. ' + jqXHR.status + '. ' + textStatus + '. ' + errorThrown); fetchtoken(); } console.log('Server error. Please try again.'); }); } 

更新:响应头[/ fetchtoken]

 HTTP/1.1 200 OK Server: nginx Date: Sat, 25 Feb 2017 13:14:44 GMT Content-Type: application/json; charset=utf-8 Content-Length: 48 Connection: keep-alive Access-Control-Allow-Origin: * set-cookie: _csrf=2bd-cKtDQuEeKrACQAJr-Rhu; Path=/ set-cookie: connect.sid=s%3AMIz1TNRpYTI7Pk8uO6MgzOd5M6a31cyW.0RYKkWw9w6om7GGQSawE89hDskJJ5nQ7HZdI24jdmF8; Path=/; HttpOnly ETag: W/"30-GhAlz0fz9nu44Q5ZUCXJSw" Cache-Control: max-age=0, no-cache, no-store, must-revalidate Pragma: no-cache X-Xss-Protection: 1; mode=block X-Frame-Options: SAMEORIGIN X-Content-Type-Options: nosniff 

更新:响应头[login]

 HTTP/1.1 403 Forbidden Server: nginx Date: Sat, 25 Feb 2017 13:14:44 GMT Content-Type: text/html; charset=utf-8 Transfer-Encoding: chunked Connection: keep-alive Access-Control-Allow-Origin: * set-cookie: _csrf=WOF-6ruV7OretakTDESz0gdv; Path=/ set-cookie: connect.sid=s%3A6ft632U8-ykvlzSrUiPcBM4ULBHtIl_A.FuiSoiQ6%2BC22ThR%2Br5PwwHgCLP1nve2mFSLwoluLJTs; Path=/; HttpOnly ETag: W/"445-JIguc6Asgpp7T6tcOBhH9w" Content-Encoding: gzip 

HTML元素:

 <input id="_csrf" type="hidden" value="1Lf4MPRe-vaeSnvXKNmDIlGIBx4epL6izVFA" name="_csrf"> 

当它实际上是asynchronous的时候,你使用fetchtoken函数就好像它是同步的。

尝试使用以下命令replacefetchtoken函数:

 function fetchtoken(){ var settings = { "url": base_url+"/fetchtoken", "method": "GET", }; return $.ajax(settings).done(function(data) { return data.token; }).fail(function(jqXHR, textStatus, errorThrown) { if (jqXHR.status == 403 || jqXHR.status == 405) { console.log('Server error. ' + jqXHR.status + '. ' + textStatus + '. ' + errorThrown); return fetchtoken(); } return null; console.log('Server error. Please try again.'); }); } 

并用以下代替你的loginfunction:

 function login(){ var email = $('.email').val(); var password = $('.password').val(); pageCheck = "login" fetchtoken().then(function(csrfToken) { if ((email != '') && (password != '')) { var settings = { "url": base_url+"/login", "method": "POST", dataType: 'json', data:{ "email": email, "password": password, "_csrf": csrfToken }, crossdomain : true }; $.ajax(settings).done(function(data) { if (data.status === true) { alert("Logged in!"); // var data = data.data; // token = data.accesstoken; // var userId = data.id; // localStorage.setItem('userId', userId); // localStorage.setItem('token', token); // var userInfo = JSON.stringify(data); // localStorage.setItem('pollVisited', data.pollVisitedFlag); // window.open('home', '_self'); } else { if(data.msg == "Email id doesnt exist"){ $('#loginError').modal('show'); } else{ $('.preloader').fadeIn(); checkactiveUser(email, pageCheck); // var h = $('.password').parent().find('.highlighter'); // h.show().html('Enter a valid password'); // h.addClass('shake animated'); // $('.password').addClass('error'); // h.one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function() { // $(this).removeClass("shake animated"); // setTimeout(function() { // h.fadeOut(300); // }, 5000); // }); } } }).fail(function(jqXHR, textStatus, errorThrown) { if (jqXHR.status == 403 || jqXHR.status == 405 || jqXHR.status == 502) { console.log('Server error. ' + jqXHR.status + '. ' + textStatus + '. ' + errorThrown); loginPage(); } console.log(jqXHR.status + textStatus + errorThrown); }); } else { loginerror(); } }); }