NodeJS 函数User.findOrCreate在做什么,什么时候在passport中调用它?

voj3qocg  于 2023-05-06  发布在  Node.js
关注(0)|答案(2)|浏览(125)

我找不到关于这个函数的文档,因此我不能使它正常工作。什么时候调用这个函数,它在做什么,它的第一个参数是什么?我试图从passport中获取访问令牌,但无论如何都无法访问。

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

  }
));

如何从passport获取访问令牌?

wlzqhblo

wlzqhblo1#

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的护照代码,并有一些注解来解释它。这里假设你使用的是类似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')
qltillow

qltillow2#

如果您想使用findOrCreate,请尝试npm包mongoose-findorcreatesupergoose
例如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);
        });
    }
));

相关问题