我在Node Express和CSurf中遇到问题-403(禁止)无效的csrf令牌。浏览其他答案并尝试通过搜索可以找到的所有内容,我只是无法克服这一点。

我在邮递员中测试了该api,它工作得很好。

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

后端代码:

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() {
        //Retrieving 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


更新:响应头[登录]

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">

最佳答案

当实际上是异步的时,您正在使用fetchtoken函数,就好像它是同步的一样。

尝试将fetchtoken函数替换为:

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


并将您的login函数替换为:

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

08-07 12:52