简体   繁体   English

未定义Passport req.user。 deserializeUser返回一个有效的用户

[英]Passport req.user is undefined. deserializeUser is returning a valid User

I'm using Express, MongoDB with MongoJS and Passport. 我正在使用Express,带有MongoJS和Passport的MongoDB。 My front-end is just vanilla JS on another domain. 我的前端只是另一个域上的普通JS。 Currently, Express is saving a user from the front-end's form into Mongo and returning a cookie that the browser is properly saving. 目前,Express正在将用户从前端表单保存到Mongo中,并返回浏览器已正确保存的cookie。 However, when I go initiate another route via a GET request from the front-end the result I get req.user === 'undefined' and req.isAuthenticated() === false . 但是,当我通过前端的GET请求发起另一条路线时,结果是req.user === 'undefined'req.isAuthenticated() === false Passport seems to run passport.serializeUser and passport.deserializeUser correctly yet the user isn't getting set onto the request. Passport似乎可以正确运行passport.serializeUserpassport.deserializeUser ,但用户并未被设置为请求。 I must be missing something? 我肯定错过了什么?

Here's my code: 这是我的代码:

app.use(cookieParser('supernova'));
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json(options));
app.use(session({
    secret: 'supernova',
    resave: false,
    saveUninitialized: false,
    cookie: {
        maxAge: 60*60*1000,
        secure: false,
        httpOnly: false,
        domain: 'localhost'
    }
}));
app.use(passport.initialize());
app.use(passport.session());

Passport: 护照:

passport.use('local', new LocalStrategy(
    {passReqToCallback : true},
    (req, username, password, done) => {
        db.users.findOne({'username': username}, (error, user) => {
            if (error) {return done(error);}
            if (user) {
                log('User already exists');

                return done(user);
            } else {
                crypt.hashPassword(password, ((encryptedPassword) => {
                    var newUser = new User({username: username, password: encryptedPassword});
                    db.users.save(newUser, (err, data) => {
                        if (err) {
                            log(err);
                            return done(err)
                        }
                        log(data);

                        return done(null, data);
                    })
                }));
            }
        })
    }
));

passport.serializeUser(function(user, done) {
    log('serialize: ' + user._id)
    done(null, user._id);
});

passport.deserializeUser(function(id, done) {
    log('deserialize: ' + id)
    db.users.findOne({_id: mongojs.ObjectId(id)}, (err, user) => {
    log(user)
        if(err) {
            log(err);
            return done(err);
        }
        return done(err, user);
    });
});

function loggedIn(req, res, next) {
    log('logged in: ' + req.user);
    // log(req.session)
    if (req.isAuthenticated()) { return next(); }
    req.session.error = 'Please sign in!';
}

Headers: 头:

app.use((req, res, next) => {
    res.setHeader('Access-Control-Allow-Origin', 'http://localhost:4200');
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
    res.setHeader('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
    res.setHeader('Access-Control-Allow-Credentials', true);
    next();
});

Routes: 路线:

app.post('/register', passport.authenticate('local', {session: true}), (req, res) => {
    req.session.save(() => {
        return res.redirect('/')
    })
});
app.use('/api', loggedIn, maps);

Initial Sign Up call made from front-end: 从前端发出的初始注册电话:

document.getElementById('signup').addEventListener('submit', function (e) {
    e.preventDefault();
    window.fetch(process.env.DB_API_URI + '/register', {
        method: 'POST',
        headers: {
            'Accept': 'application/json',
            'Content-Type': 'application/json',
        },
        credentials: 'include',
        body: JSON.stringify({
            username: document.getElementById('signUpUsername').value,
            password: document.getElementById('signUpPassword').value
        })
    })

2nd Front-End call where req.user is empty in Express: Express中req.user为空的第二个前端呼叫:

return window.fetch(process.env.DB_API_URI + '/maps/' + mapId, {
            method: 'GET',
            headers: {
                'Content-Type': 'application/json'
            },
            credentials: 'include'
        })

The problem was the browser was sending two HTTP requests, an OPTIONS and a GET request. 问题在于浏览器正在发送两个HTTP请求,一个OPTIONS和一个GET请求。 The OPTIONS request was not sending over the credentials and thus failing the authentication check. OPTIONS请求未通过凭据发送,因此未通过身份验证检查。 I bypassed this by updating my function to the following: 我通过将函数更新为以下内容来绕过此操作:

function loggedIn(req, res, next) {
    log('logged in: ' + req.isAuthenticated());
    if (req.isAuthenticated() || req.method === 'OPTIONS') {
        return next();
    }
    req.session.error = 'Please sign in!';
    res.status(400).send();
}

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

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