10

私は、Google、Facebook、および Twitter のログインのみに Passport.js を使用しています。

Node.js v0.8.19 と Express.js 3.1.0、および Passportjs バージョン 0.1.16。(パスポート-facebook - 0.1.5、ツイッター - 0.1.4 パスポート-goolge-oauth - 0.1.5)

Passport.js を実行しているアプリの 1 時間ほど後に、ユーザーの req.user セッションへのシリアル化が停止した後、しばらくの間はすべて正常に動作します。

FacebookとGoogleは、それぞれのAPIから意味のある完全なデータを受け取っています

passport.use(new FacebookStrategy({
    clientID: FACEBOOK_APP_ID,
    clientSecret: FACEBOOK_APP_SECRET,
    callbackURL: "http://localhost:3000/auth/facebook/callback"
  },
  function(accessToken, refreshToken, profile, done) {
      var temp = {} 
      temp.name = profile.displayName
      temp.id = profile.id
      console.log(temp)
      return done(null, temp);
}));

ここのconsole.logはユーザーIDと名前を正常に出力しますが、呼び出した後

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

passport.deserializeUser(function(obj, done) {
  done(null, obj);
});

シリアライズとデシリアライズは、passport-facebook の例から取られています。

ユーザーは req.user に関連付けられません。

Twitter はそこまで到達しません。コールバック URL に戻った後、Twitter は次のエラーを返します。

Error: failed to find request token in session
[03/11 23:28:24 GMT]     at Strategy.OAuthStrategy.authenticate            

注:これらの障害は一定期間後にのみ発生し、しばらくの間は正常に動作します。そのため、クックの代わりにセッションをメモリに保存するなど、メモリの問題である可能性があると思います。

これは私の高速アプリ構成です

app.configure(function(){
  app.set('port', process.env.PORT || 8080);
  app.set('views', __dirname + '/views');
  app.set('view engine', 'jade');
  app.use(express.favicon());
  app.use(express.logger('dev'));
  app.use(express.cookieParser());
  app.use(express.bodyParser());
  app.use(express.methodOverride());
  app.use(express.cookieSession({ secret: 'tobo!', cookie: { maxAge: new Date(Date.now() +     3600000), }}));
  app.use(passport.initialize());
  app.use(passport.session());
  app.use(app.router);
  app.use(express.static(__dirname + '/public'));
});

メーリングリストなどを見ましたが、この問題に該当するものは見つかりませんでした。localhost と nodejitsu サーバーで確認しました。すべてがしばらくの間機能し、その後失敗します。

4

3 に答える 3

26

まず、シリアル化と逆シリアル化の意味を理解する必要があります。

1)最初の質問に従ってserializeUser、ユーザーオブジェクトを取得し、戻ったときにセッションに必要な情報を保存します。done(null, user)

2)deserializeUserセッションに保存されている情報(すべてのリクエストでcookieSessionによって送信される)を取得し、セッションがユーザーに対してまだ有効であり、if(!err) done(null,user)trueであるかどうかを確認し、ユーザーをセッションに保持し、セッションelse done(err,null)から削除して、にリダイレクトしますapp.get('/auth/:provider/callback')セッションがタイムアウトしたかどうかを確認した後、ユーザーを送信するものは何でも。これにより、2番目の質問の内容が明確になります。

于 2013-03-15T17:05:40.877 に答える
6

なぜ問題が発生したのかはまだわかりませんが、次のようにして解決しました。

変化

  app.use(express.cookieSession({ secret: 'tobo!', cookie: { maxAge: new Date(Date.now() +     3600000), }}));

app.use(express.cookieSession({ secret: 'tobo!', maxAge: 360*5 }));

deserializeUserは渡されたCookieを返すだけなので、ユーザーオブジェクト全体のシリアル化は機能するはずです。ただし、ユーザーオブジェクト全体をシリアル化しないことで、機能しています。

passport.serializeUser(function(user, done) {
    console.log('serializeUser: ' + user._id)
    done(null, user._id);
});

passport.deserializeUser(function(id, done) {
    db.users.findById(id, function(err, user){
        console.log(user)
        if(!err) done(null, user);
        else done(err, null)  
    })
});

これを行って以来、問題は発生していません。

于 2013-03-15T16:27:34.837 に答える