web-dev-qa-db-fra.com

Que fait la fonction User.findOrCreate et quand est-elle appelée dans le passeport?

Je ne trouve pas de documentation sur cette fonction et je ne peux donc pas la faire fonctionner correctement. Quand cette fonction est-elle appelée, que fait-elle et que prend-elle comme premiers paramètres? J'essaie d'obtenir un jeton d'accès à partir du passeport, mais je n'y parviens pas de toute façon.

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

  }
));

Comment puis-je obtenir un jeton d'accès du passeport?

42
Tommz

User.findOrCreate est une fonction inventée qui représente la fonction dont vous disposez pour trouver un utilisateur par identifiant Facebook, ou pour en créer un si l'utilisateur n'existe pas. Je pense que votre premier problème est que votre URL de rappel va juste à votre racine, donc vous n'obtiendrez probablement jamais cette fonction.

Votre URL de rappel doit être semblable à http://localhost:3000/auth/facebook/callback.

Et puis gérer cette URL:

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

À ce stade, l'authentification est terminée. accessToken vous est retourné - "ceci est nécessaire chaque fois que l'application appelle une API pour lire, modifier ou écrire les données Facebook d'une personne spécifique en son nom". Vous devez l'enregistrer dans une table où vous stockez des jetons d'accès pour un utilisateur. profile est l'autre variable clé car il s'agit des informations sur l'utilisateur (quelles informations dépendent du service).

Ce que vous faites à l'intérieur de cette fonction dépend de vous. Alors, faites votre propre User.findOrCreate. Voici le code du passeport pour Facebook avec quelques commentaires pour l'expliquer. Cela suppose que vous utilisez quelque chose comme MongoDB et avez une table User. User dans ce cas est la variable que vous avez déclarée qui peut s'interfacer avec la table 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);
            }
        });
    }
));

Personnellement, j'utilise également une table "d'adhésion" pour suivre plusieurs comptes par utilisateur (afin qu'ils puissent s'authentifier avec plusieurs comptes), comme je l'ai configuré via mangouste. C'est en fait là que je stocke ce jeton d'accès. Je préfère cela à avoir une colonne facebook dans la table des utilisateurs .... mais c'est à vous.

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

et à ce titre, ma version de User.findOrCreate commence comme ceci:

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

où l'appartenance est ce modèle ci-dessus, et est défini comme une variable comme:

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

Si vous souhaitez utiliser findOrCreate, essayez le package npm mongoose-findorcreate , ou supergoose

par exemple. 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);
        });
    }
));
3
Vinnie James