什么是函数User.findOrCreate做什么,什么时候在护照中调用?

我无法find关于此function的文档,因此我无法使其正确工作。 什么时候该函数被调用,它在做什么,作为第一个参数是什么? 我试图从护照获取访问令牌,但无法以任何方式达到它。

passport.use(new FacebookStrategy({ clientID: APP_ID, clientSecret: APP_SECRET, callbackURL: "http://localhost:3000/", }, function(accessToken, refreshToken, profile, done) { User.findOrCreate({// what are these parameters?}, function (err, user) { // when is this function called and what is it doing? }); } )); 

我怎样才能从护照获得访问令牌?

User.findOrCreate是一个组成的函数,它表示用Facebook ID查找用户所需的任何函数,或者如果用户不存在,则创build一个函数。 我认为你的第一个问题是,你的callbackURL只是你的根,所以你可能永远不会去那个function。

您的回叫url应该像http://localhost:3000/auth/facebook/callback

然后处理该URL:

 app.get('/auth/facebook/callback', passport.authenticate('facebook', { failureRedirect: '/login' }), function(req, res) { res.redirect('/'); }); 

此时authentication完成。 accessToken会返回给你 – “当应用程序调用API来代替它们读取,修改或写入特定人员的Facebook数据时,就需accessToken 。 您应该将其保存在某个用于存储用户访问令牌的表格中。 profile是另一个关键的variables,因为这是关于用户的信息(什么信息取决于服务)。

你在这个function里面做什么取决于你 。 所以,做你自己的User.findOrCreate 。 这里是来自护照的代码,用一些评论来解释它。 这假定你正在使用类似MongoDB的东西,并有一个User表。 在这种情况下, User是您声明可以与User表进行交互的任何variables。

 //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); } }); } )); 

就我个人而言,我也使用“会员”表来跟踪每个用户的多个帐户(这样他们就可以用多个帐户进行身份validation),就像我通过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如此,我的User.findOrCreate版本是User.findOrCreate开始的:

 function(accessToken, refreshToken, profile, done) { Membership.findOne({ providerUserId: profile.id }, function(err,membershipData) { //blah blah blah 

其中成员资格是上述模型,并被定义为一个variables:

 var Membership = require('./models/membership.js') 

如果您想使用findOrCreate ,请尝试npm包mongoose-findorcreate或supergoose

mongoose-findorcreate

 var mongoose = require('mongoose'); mongoose.connect('mongodb://localhost'); var findOrCreate = require('mongoose-findorcreate') var Schema = mongoose.Schema; var UserSchema = new Schema({ facebookId: Number}); UserSchema.plugin(findOrCreate); var User = mongoose.model('User', UserSchema); passport.use(new FacebookStrategy({ clientID: 'clientID', clientSecret: 'clientSecret', callbackURL: "/auth/facebook/callback" }, function(accessToken, refreshToken, profile, cb) { User.findOrCreate({ facebookId: profile.id }, function (err, user) { console.log('A new uxer from "%s" was inserted', user.facebookId); return cb(err, user); }); } ));