User.findOrCreate
是一个虚构的函数,代表你必须通过Facebook ID找到一个用户的任何函数,或者如果用户不存在的话创建一个.我认为你的第一个问题是,你的回调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 passport的代码,并附有一些解释.这假设您使用的是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')