2017-02-18 15 views
0

私はNode.JSとExpressの初心者ですが、完全に機能するWebアプリケーションを作成することができました。私は、プロダクションモードになると、セッションをRAMに保存していたことに気付きました。代わりに、私はそれらをMongo Storeに保管したいと思います。PassportJSで動作するMongoDB Storeを取得できません

私はPassportを使用しているので、Mongo Storeで動作するように関数をシリアル化および逆シリアル化する方法を知りたいと思います。セッションを保存するとうまくいくように見えますが(データベースに表示されます)、フェッチできません。

もっと正確には、セッションIDを取得してデータベースからユーザーをフェッチする方法を知りたいと思います。ここで

は私のサーバーのコードです:ここで

var store = new MongoDBStore(
     { 
     uri: process.env.MONGODB_URI, 
     mongooseConnection: db, 
     collection: 'mySessions' 
     }); 

    // Catch errors 
    store.on('error', function(error) { 
     throw error; 
    }); 

app.use(session({ 
    secret: '****', 
    resave: true, 
    store: store, 
    saveUninitialized: true, 
    cookie: { 
     maxAge: 7 * 24 * 60 * 60 * 1000} 
    })); 
app.use(passport.initialize()); 
app.use(passport.session()); 

passport.use(new GoogleStrategy({ 
    clientID: process.env.GOOGLE_CLIENT, 
    clientSecret: process.env.GOOGLE_SECRET, 
    callbackURL: process.env.CALLBACK_URL 
    }, 
    function(accessToken, refreshToken, profile, done) { 
     var user = new User(); 

     var profileUser = user.extractProfile(profile); 

     done(null, profileUser.email); // The only info I need is the user email address 

    } 
)); 

passport.serializeUser(function(user, done) { 
    console.log('Serializing user:'+user); // user returns the email address 
    done(null, user); // The session is stored 
}); 

var Sessions = db.collection('mySessions'); 

passport.deserializeUser(function (id, done) { 

    console.log('Deserializing user:'+id); // What clearly doesn't work here, is that I'm trying to fetch a document using the email address instead of the "_id"... 

    return Sessions.findOne({ user: id }, function (error, user) { 
     console.log('Found :'); 
     console.log(user); 
     return done(error, user); 
    }); 
}); 

はモンゴストア内の1つのエントリです:

{ 
    "_id": "10yEo3rU4Qumf2jw3346UtY0cCnRWNhc", 
    "session": { 
     "cookie": { 
      "originalMaxAge": 604800000, 
      "expires": { 
       "$date": "2017-02-25T13:46:57.231Z" 
      }, 
      "secure": null, 
      "httpOnly": true, 
      "domain": null, 
      "path": "/", 
      "sameSite": null 
     }, 
     "passport": { 
      "user": "le*****@*****.com" 
     } 
    }, 
    "expires": { 
     "$date": "2017-02-25T13:46:57.231Z" 
    } 
} 

は、私は適切にデシリアライズ機能を動作させることができた場合と信じて、すべてのもの以前と同じように動作します。どのようにそれを行う上の任意のアイデアですか?

(編集)私はこのように、(私はモンドデータベースからIDを持って)私のセッションIDでの手動検索を実行するためにデシリアライズ機能を編集した:

passport.deserializeUser(function (id, done) { 

    console.log('Deserializing user:'+id); 
    return Sessions.findOne({ _id: 'faogaErvZirU2lVpo49M-Bkz7zuQwbhP' }, function (error, user) { 
     console.log('Found :'); 
     console.log(user); 
     return done(error, user.session.passport.user); 
    }); 
}); 

そしてそれはに動作します。だから私が間違っていない限り、私が知る必要があるのは、クッキーから_idを取得する方法だけです。

ありがとうございました!

答えて

0

答えを探していたあと、私はGitHubで同様のプロジェクトをチェックし、より正確には、Passportとストアドセッションの統合を成功させました。

私は自分の問題を理解しました:私は自分のセッションではなく私のユーザーを保存する必要がありました(Mongo Storeは既にそうしていました)。したがって、私は、データベースに新しいユーザーを作成したり、そのプロファイルを取得するために私のGoogleの戦略を変更:

var UserDB = db.collection('users'); 

passport.use(new GoogleStrategy({ 
clientID: process.env.GOOGLE_CLIENT, 
clientSecret: process.env.GOOGLE_SECRET, 
callbackURL: process.env.CALLBACK_URL, 
}, 
function(token, refreshToken, profile, done) { 
    process.nextTick(function() { 

    UserDB.findOne({ 'id': profile.id }, function(err, user) { 
     if (err) 
     return done(err); 
     if (user) { 
     return done(null, user); 
     } else { 

     var newUser = {}; 
     newUser.id = profile.id; 
     newUser.token = token; 
     newUser.name = profile.displayName; 
     newUser.email = profile.emails[0].value;    
     UserDB.insert({ 'id': profile.id, 'token': token, 'name': profile.displayName , 'email': profile.emails[0].value}, function (err) { 
       if (err) { 
        throw err; 
       } 
       return done(null, newUser); 
     }); 
    } 
    }); 
}); 
})); 

そこから、私は、データベース内のユーザーを検索する必要がありました:

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

passport.deserializeUser(function (user, done) { 

    return UserDB.findOne({ id: user.id }, function (error, user) { 

     return done(error, user); 
    }); 
}); 

私の間違いは、serializeUserとdeserializeUserがすべてセッションに関することだと思っていました。セッションは、Express-sessionとMongoDB Storeで100%管理されていたので、心配する必要はありませんでした。

関連する問題