Tom*_*mmz 45 node.js passport.js
我找不到关于此功能的文档,因此我无法使其正常工作.该函数何时被调用,它正在做什么以及它作为第一个参数采取了什么?我正试图从护照获取访问令牌,但无论如何都无法访问它.
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?
});
}
));
Run Code Online (Sandbox Code Playgroud)
如何从护照获取访问令牌?
Mik*_*Dev 69
User.findOrCreate
是一个虚构的函数,表示您通过Facebook ID查找用户的任何功能,或者如果用户不存在则创建一个函数.我认为你的第一个问题是你的回调网址只是你的根,所以你可能永远不会去那个功能.
你的回调网址应该是这样的http://localhost:3000/auth/facebook/callback
.
然后处理该URL:
app.get('/auth/facebook/callback',
passport.authenticate('facebook', { failureRedirect: '/login' }),
function(req, res) {
res.redirect('/');
});
Run Code Online (Sandbox Code Playgroud)
此时身份验证已完成.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);
}
});
}
));
Run Code Online (Sandbox Code Playgroud)
我个人也使用"会员"表来跟踪每个用户的多个帐户(因此他们可以通过多个帐户进行身份验证),因为我通过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);
Run Code Online (Sandbox Code Playgroud)
因此,我的版本User.findOrCreate
开始像这样:
function(accessToken, refreshToken, profile, done) {
Membership.findOne({
providerUserId: profile.id
}, function(err,membershipData) {
//blah blah blah
Run Code Online (Sandbox Code Playgroud)
成员资格是上述模型,并被定义为变量:
var Membership = require('./models/membership.js')
Run Code Online (Sandbox Code Playgroud)
如果您想使用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);
});
}
));
Run Code Online (Sandbox Code Playgroud)