Экспресс-паспорт с использованием логина Facebook и локального логина
Я использую промежуточное программное обеспечение Passport для ExpressJS и не могу найти способ использовать стратегию passport-local и стратегию passport-facebook вместе. Я хотел бы настроить его так, чтобы пользователь создал учетную запись на моем сайте, а затем, если он этого захочет, он мог войти в Facebook, чтобы вы могли видеть своих друзей, которые также используют сайт. Однако я не знаю, что такое вошедший в систему пользователь, когда возвращаются данные API Facebook.
Когда кто-то создает учетную запись, его данные (имя пользователя, электронная почта, т. Д.) Хранятся в базе данных. Когда они затем войдут в Facebook, я хотел бы просто обновить базу данных и сеанс, чтобы теперь включить часть информации, возвращаемой API Facebook (facebookID, AccessToken и т. Д.). Как этого достичь?
Вот код, который я могу использовать для доступа к возвращенным данным Facebook. Строка с User.findOne работает только в том случае, если запись базы данных уже была синхронизирована с Facebook ранее. Можно ли как-то передать данные req.session, чтобы определить, кто в данный момент вошел в систему, и обновить свой профиль?
passport.use(new FacebookStrategy({
clientID: FACEBOOK_APP_ID,
clientSecret: FACEBOOK_APP_SECRET,
callbackURL: "http://localhost:3000/auth/facebook/callback",
//callbackURL: "http://localhost:3000"
profileFields: ['id', 'displayName']
},
function(accessToken, refreshToken, profile, done) {
User.findOne({facebookID: profile.id}, function(err, user) {
if (err) { return done(err); }
user.facebookID = profile.id;
user.facebookToken = accessToken;
user.save();
return done(null, user);
});
}
));
2 ответа
Чтобы получить текущего пользователя, вам нужно добавить passReqToCallback : true
вариант в facebookStrategy
passport.use(new FacebookStrategy({
clientID: FACEBOOK_APP_ID,
clientSecret: FACEBOOK_APP_SECRET,
callbackURL: "http://localhost:3000/auth/facebook/callback",
//callbackURL: "http://localhost:3000"
profileFields: ['id', 'displayName'],
passReqToCallback : true // NEED THIS!!
},
function(req, accessToken, refreshToken, profile, done) {
if (req.user) {
User.findOne({username: req.user.username}, function(err, user) {
if (err) { return done(err); }
user.facebookID = profile.id;
user.facebookToken = accessToken;
user.save();
return done(null, user);
});
}
else{
console.log("attempted facebook auth from non-logged in user");
return done(null, null);
}
}
));
Я не знаком с модулем Facebook паспорта, но я думаю, что вы можете получить доступ к своей локальной базе данных пользователей внутри этого:
function(accessToken, refreshToken, profile, done) {
User.findOne({facebookID: profile.id}, function(err, user) {
if (err) { return done(err); }
user.facebookID = profile.id;
user.facebookToken = accessToken;
user.save();
return done(null, user);
});
Примерно так должно быть хорошо:
var User = require('./models/user');
passport.use(User.createStrategy());
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());
function(accessToken, refreshToken, profile, done) {
//Make sure you have your user's email field and match that with
//the email field you got from Facebook
User.findOne({email: profile.email}, function(err, user) {
if (err) { return done(err); }
user.facebookID = profile.id;
user.facebookToken = accessToken;
user.save();
return done(null, user);
});
Я не уверен, если profile
есть поле электронной почты, но я думаю, что это должно быть где-то в профиле.
Тем не менее, я понимаю, что это не будет работать, если ваш пользователь имеет только имя пользователя и пароль.