简体   繁体   English

Express + Passport-在后续请求中未定义req.session.passport

[英]Express + Passport - req.session.passport undefined on subsequent requests

I have started developing little project where I have React with Redux on the client side, and the backend is being done with Node, Express and Passport.js I will try to describe best What I am struggling with for some hours. 我已经开始开发一个小项目,其中我在客户端使用React与Redux进行交互,后端正在使用Node,Express和Passport.js完成,我将尽力描述几个小时以来我一直在努力的东西。 after authentication, when user is being send from server to client, field req.session.passport is set, along with req.user. 验证后,在将用户从服务器发送到客户端时,将设置req.session.passport字段以及req.user。 but when i do next request, no matter is it logout or for example /something/add these fields are undefined. 但是当我下一个请求时,无论是注销还是/ something / add,这些字段都是未定义的。

when authenticating, serializeUser is being called, but deserializeUser not and i dont think it should here, maybe im wrong. 进行身份验证时,调用了serializeUser,但未调用deserializeUser,我不认为这应该在这里,也许是我错了。 as far as I went into debugging the problem, req.login is being called too. 就我调试问题而言,req.login也被调用。 on the next requests it seems that passport isnt doing anything, and i'm out of ideas and anwsers from SO and google. 在下一个请求中,似乎护照没有做任何事情,而且我没有SO和Google的想法和答案。 i didnt try the custom callback. 我没有尝试自定义回调。

req.session just before sending anwser to client looks like: 将anwser发送到客户端之前的req.session看起来像:

Session {
  cookie:
   { path: '/',
     _expires: 2017-01-11T02:31:49.235Z,
     originalMaxAge: 14400000,
     httpOnly: false,
     secure: false } }

the code on the server side is: 服务器端的代码是:

    passport.serializeUser(function(user, done) {
        done(null, user._id);
    });

    passport.deserializeUser(function(id, done) {
        global.Models.User.findById(id, function(err, user) {
            done(err, user);
        });
    });

    passport.use(new LocalStrategy(
        {
            usernameField: 'login',
            passwordField: 'password',
            passReqToCallback: true
        },
        function(req, login, password, done) {
            global.Models.User.logIn({login: login, password: password}, function(err, user){

                if(err){
                    done(err);
                }
                else{
                    done(null, user);
                }

            });
        }
    ));
    var app = express();
    var router = express.Router();
    router.use(cookieParser());
    router.use(bodyParser.urlencoded({extended: false}));
    router.use(bodyParser.json());
    router.use(session({
        cookie : {
            secure : false,
            maxAge : (4 * 60 * 60 * 1000),
            httpOnly: false
        },
        secret: this._config.session.secret,
        resave: false,
        saveUninitialized: true
    }));
    router.use(passport.initialize());
    router.use(passport.session());

    require('./Router')();
    app.use(router);

session object here is the express-session. 会话对象是快速会话。 code under is the Router.js required above 下面的代码是上面所需的Router.js

var User = require('../Models/User');
var News = require('../Models/News');

var passport = global.Application.getInstanceOf("passport");

function setRoutes(){
    router.use(function (req, res, next) {

        var log = global.Application.getInstanceOf("logger");

        var clientIP =  req.headers['x-forwarded-for'] || 
                        req.connection.remoteAddress || 
                        req.socket.remoteAddress ||
                        req.connection.socket.remoteAddress;

        log.log("info", req.method + " request from ip: " + clientIP);

        res.header('Access-Control-Allow-Origin', 'http://localhost:8080');
        res.header('Access-Control-Allow-Credentials', true);
        res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,PATCH,OPTIONS');
        res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, Content-Length, X-Requested-With');

        if('OPTIONS' == req.method){
            res.sendStatus(200);
        }
        else{
            next(); 
        }       

    });

    router.get('/ping', function(req, res){
        res.send('ping');
    });

    router.get('/login/:login', (req, res) => {
        Database.client.query(Database.queries.USER_LOGIN, {login: req.params.login}, {useArray: true}, 
        (err, rows) => {
            if(err){
                res.send({error: "ERROR_DATABASE"});
            }
            else{
                res.send(rows[0][0]);
            }
        });
    });

    router.post('/login', passport.authenticate('local', {session: true}), 
        function(req, res){
            console.log(req.session);
            req.session.save();
            res.send(req.user);
        }
    );

    router.post('/register', (req, res) => {
        User.create(req.body, (err, result) => {
            if(err){
                res.send({error: "ERROR_DATABASE"});
            }
            res.send(result);
        });
    });

    router.get('/logout', function(req, res){
        console.log(req.session);
        req.logout();
        res.sendStatus(200);
    });

    router.post('/cms/article', isAuthenticated, (req, res) => {
        res.send("BLA");
    });

    function isAuthenticated(req, res, next){
        console.log(req.user);
        console.log(req.session);
        console.log(req.session.passport);
        if(req.isAuthenticated()){
            next();
        }
        else{
            res.send("OK");
        }
    }
}

module.exports = setRoutes;

I have solved the problem. 我已经解决了问题。

Explanation: Cookie was being sent by express to client, but it wasn't saved. 说明:Cookie已通过快递发送给客户,但未保存。 For that, it needed change from using $.post to $.ajax with xhrFields option set to {withCredentials: true}. 为此,需要将xhrFields选项设置为{withCredentials:true},从使用$ .post更改为$ .ajax。

Aside from that, the problem could also be that, that cookieParser probably need to know cookie secret too now. 除此之外,问题还可能是cookieParser现在可能也需要知道cookie的秘密。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM