Как получить данные профиля в сложном случае, используя passport-facebook в node.js - PullRequest
0 голосов
/ 27 октября 2018

Я использую passport-facebook, но так -

app.get('/oauth/facebook', passport.authenticate('facebook', {}));

не соответствует моим требованиям, потому что мне нужно сохранить данные в сеансе. Это не будет работать, если я просто добавлю passport.authenticate в другую функцию, например:

app.get('/oauth/facebook', function (req, res, next) { 
    passport.authenticate('facebook', {});
}); // doesn't work

Но это работает, если я вызываю эту функцию, например:

const fbAuth = (req, res) => {
    req.session.isRegisterUser = req.query.isRegisterUser || false;
    req.session.regUserId = req.params.id > 0 ? req.params.id : null;
    req.session.redirectUrlAfterSignIn = req.query.redirectUrl ? req.query.redirectUrl : null;

    return passportFacebook.authenticate('facebook', {}, function() {
        // NEVER called
        console.log('auth cb');
    });
};

// this is the only way I could pass (req, res)
router.get('/oauth/:id/facebook', 
    (req, res) => fbAuth(req, res)(req, res));

Он не вызывает функцию третьего параметра, но перенаправляет. После этого он переходит к функции обратного вызова:

const fbCb = (req, res) => {
    return console.log(req.session.regUserId);
};

router.get('/oauth/facebook/callback', (req, res) => fbCb(req, res)(req, res));

И это работает, но как я могу получить данные профиля? Потому что в моем URL есть только параметр code, который является access_token, если я правильно понимаю.

Я инициализирую Стратегию так же, как в документации:

const passport = require('passport');
const Strategy = require('@passport-next/passport-facebook').Strategy;

passport.use(new Strategy({
        clientID: process.env.FACEBOOK_APP_ID,
        clientSecret: process.env.FACEBOOK_SECRET,
        callbackURL: 'http://localhost:3001/api/oauth/facebook/callback',
        graphApiVersion: 'v3.1',
        // scope: ['email']
    },
    function(accessToken, refreshToken, profile, cb) {
        // NEVER called
        console.log(`accessToken`, accessToken);
        console.log(`profile`, profile);
        return cb(null, profile);
    }
));

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

passport.deserializeUser(function(id, done) {
    return models.User.findById(id).then(user=>{
        done(null, user);
    }).catch(function (err) {
        done(null, null);
    });
});

module.exports = passport;

Но function(accessToken, refreshToken, profile, cb) никогда не звонил. Однако мне нужен доступ к запросу, чтобы я мог проверить свои данные сеанса, поэтому мне нужно все это в моей функции обратного вызова, а не здесь.

Итак, я немного расстроен, почему это так сложно. Чтобы решить эту проблему, вероятно, я могу получить данные по URL https://graph.facebook.com/v3.1/me?... и проанализировать JSON. Но зачем мне тогда эта библиотека?!

Вы можете найти весь код здесь

1 Ответ

0 голосов
/ 28 октября 2018

Я обнаружил, что необходимо позвонить passportFacebook.authenticate во второй раз, чтобы перезвонить. И это можно сделать внутри функции, единственное, что вы должны вернуть результат функции passportFacebook.authenticate (вызвать ее). Финальный код

...