Ответ 1
User.findOrCreate
- это созданная функция, которая представляет любую функцию, которую вы должны найти для пользователя по идентификатору Facebook, или создать ее, если пользователь не существует. Я думаю, что ваша первая проблема заключается в том, что ваш обратный URL-адрес просто подходит к вашему корню, поэтому вы, вероятно, никогда не доберетесь до этой функции.
Ваш URL-адрес обратного вызова должен быть как http://localhost:3000/auth/facebook/callback
.
И затем обработайте этот URL:
app.get('/auth/facebook/callback',
passport.authenticate('facebook', { failureRedirect: '/login' }),
function(req, res) {
res.redirect('/');
});
В этот момент завершена аутентификация. accessToken
вам возвращается - "это необходимо в любое время, когда приложение вызывает API для чтения, изменения или записи данных конкретного человека Facebook от их имени". Вы должны сохранить это в той таблице, где вы храните токены доступа для пользователя. profile
- это другая ключевая переменная, потому что это информация о пользователе (какая информация зависит от службы).
Что вы делаете внутри этой функции, зависит от вас. Итак, сделайте свой собственный User.findOrCreate
. Вот код из паспорта для Facebook с некоторыми комментариями, чтобы объяснить это. Предполагается, что вы используете что-то вроде MongoDB и имеете таблицу User
. User
В этом случае любая переменная, которую вы указали, может взаимодействовать с таблицей User
.
//Use facebook strategy
passport.use(new FacebookStrategy({
clientID: config.facebook.clientID,
clientSecret: config.facebook.clientSecret,
callbackURL: config.facebook.callbackURL
},
function(accessToken, refreshToken, profile, done) {
//check user table for anyone with a facebook ID of profile.id
User.findOne({
'facebook.id': profile.id
}, function(err, user) {
if (err) {
return done(err);
}
//No user was found... so create a new user with values from Facebook (all the profile. stuff)
if (!user) {
user = new User({
name: profile.displayName,
email: profile.emails[0].value,
username: profile.username,
provider: 'facebook',
//now in the future searching on User.findOne({'facebook.id': profile.id } will match because of this next line
facebook: profile._json
});
user.save(function(err) {
if (err) console.log(err);
return done(err, user);
});
} else {
//found user. Return
return done(err, user);
}
});
}
));
Лично я также использую таблицу "членства" для отслеживания нескольких учетных записей для каждого пользователя (чтобы они могли выполнять аутентификацию с несколькими учетными записями), поскольку я настраивал ее через mongoose. На самом деле я храню этот токен доступа. Я предпочитаю, чтобы это имело столбец facebook в таблице пользователя... но это зависит от вас.
var mongoose = require('mongoose'),
Schema = mongoose.Schema,
ObjectId = Schema.ObjectId;
var membershipSchema = new Schema({
provider: String,
providerUserId: String,
accessToken: String,
userId: {type: ObjectId, ref: 'User'},
dateAdded: {type: Date, default: Date.now}
});
module.exports = mongoose.model('Membership', membershipSchema);
и как таковая моя версия User.findOrCreate
начинается следующим образом:
function(accessToken, refreshToken, profile, done) {
Membership.findOne({
providerUserId: profile.id
}, function(err,membershipData) {
//blah blah blah
где членство является указанной выше моделью и определяется как переменная:
var Membership = require('./models/membership.js')