2016-12-09 4 views
1

passportJSでユーザー認証を設定しようとしています。私は自分自身でパスポートを扱うfindOrCreate関数を書くのではなく、mongoose-findorcreateというnpmパッケージを使うことにしました。mongoose-findorcourate passport-facebookを使用しているときに重複したユーザーを作成する

私のアプリをテストしていて、期待通りにFacebookのアカウント情報を使用してログインできますが、同じFacebookのログイン用にデータベースに複数のエントリを取得しているという問題があります。

これは私のユーザモデルである:

let mongoose = require('mongoose'); 
let Schema = mongoose.Schema; 

let findOrCreate = require('mongoose-findorcreate'); 

// User schema definition 
let UserSchema = new Schema(
    { 
    provider: { type: String, required: true }, 
    id: { type: String, default: 'unknown' }, 
    displayName: { type: String, default: 'unknown' }, 
    name: { type: Object }, 
    emails: { type: Array }, 
    photos: { type: Array }, 
    createdAt: { type: Date, default: Date.now }, 
    updatedAt: { type: Date, default: Date.now }, 
    } 
); 

UserSchema.plugin(findOrCreate); 

// Sets the updatedAt parameter equal to the current time 
UserSchema.pre('save', (next) => { 
    now = new Date(); 
    if(!this.updatedAt) { 
    this.updatedAt = now; 
    } 
    next(); 
}); 

module.exports = mongoose.model('user', UserSchema); 

これらは私のルートです:

let passport = require('passport'); 
let FacebookStrategy = require('passport-facebook').Strategy; 

let User = require('../models/user'); 

passport.use(new FacebookStrategy({ 
    clientID: 12345, 
    clientSecret: 'supersecretsecret', 
    callbackURL: 'http://localhost:1337/auth/facebook/callback' 
    }, 
    (accessToken, refreshToken, profile, done) => { 
    User.findOrCreate(profile, (err, user) => { 
     if (err) { 
     return done(err); 
     } 
     done(null, user); 
    }) 
    } 
)); 

passport.serializeUser(function(user, done) { 
    done(null, user.id); 
}); 

passport.deserializeUser(function(id, done) { 
    User.findById(id, function(err, user) { 
    done(err, user); 
    }); 
}); 

function redirectFB() { 
    return passport.authenticate('facebook'); 
} 

function callbackFB() { 
    return passport.authenticate('facebook', { 
    successRedirect: '/word', 
    failureRedirect: '/' 
    }) 
} 

module.exports = { redirectFB, callbackFB }; 

重複ユーザーの例:

{ 
    "_id":ObjectId("584ade8915644f1186fa8a96"), 
    "provider":"facebook", 
    "updatedAt": ISODate("2016-12-09T16:40:41.921 Z"), 
    "createdAt": ISODate("2016-12-09T16:40:41.921 Z"), 
    "photos":[ ], 
    "emails":[ ], 
    "displayName":"Miha Šušteršič", 
    "id":"10154914634234238", 
    "__v":0 
}{ 
    "_id":ObjectId("584adea3b8adfb11948ed1d6"), 
    "provider":"facebook", 
    "updatedAt": ISODate("2016-12-09T16:41:07.626 Z"), 
    "createdAt": ISODate("2016-12-09T16:41:07.625 Z"), 
    "photos":[ ], 
    "emails":[ ], 
    "displayName":"Miha Šušteršič", 
    "id":"10154914634234238", 
    "__v":0 
} 

この場合、私は把握することはできません私のコードに問題があります(プロファイルをfindOrCreate関数に渡すかどうか)。

答えて

1

findOrCreateクエリはクエリ基準に全体profileオブジェクトを渡しているので、findOrCreateが動作しません理由があります。

あなたがここに見れば:あなたが戻ってのFacebookから取得するデータの種類に応じて、https://github.com/drudge/mongoose-findorcreate/blob/master/index.js#L22

をプロファイルオブジェクトが正確にあなたのスキーマと一致しない限り、あなたのクエリは常に空を返します。あなたがここに何ができるか

はこれです:代わりに、当然の{ provider: profile.provider, id: profile.id, .... }

profileパスの

User.findOrCreate({ provider: profile.provider, id: profile.id, .... }, (err, user) => { 
    if (err) { 
    return done(err); 
    } 
    done(null, user); 
}) 

、あなたのスキーマ定義と一致するように{ provider: profile.provider, id: profile.id, .... }を修正。

0

問題が見つかりました - ユーザーデータを正しい形式でfindOrCreate関数に渡す必要がありました。

User.findOrCreate(profile._json, (err, user) => { 
     if (err) { 
     return done(err); 
     } 
     done(null, user); 
    }) 
関連する問題