如何在 node.js 中使用 passport-facebook 在复杂情况下获取个人资料数据
How to get profile data in complex case using passport-facebook in node.js
我正在使用 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。但是为什么我需要这个库呢?!
您可以找到所有代码here
我发现需要调用passportFacebook.authenticate
第二次来调用回调。并且可以在函数内部执行此操作,您唯一应该 return 函数结果 passportFacebook.authenticate
(调用它)。 Final code
我正在使用 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。但是为什么我需要这个库呢?!
您可以找到所有代码here
我发现需要调用passportFacebook.authenticate
第二次来调用回调。并且可以在函数内部执行此操作,您唯一应该 return 函数结果 passportFacebook.authenticate
(调用它)。 Final code