19

Serialize と Deserialize を実装しますか?

RedisStore は、Express を使用して私のセッション ストアとしてセットアップされます。これは、シリアライズとデシリアライズを実装していないということですか? それは自動的に起こりますか?

これらのメソッドを実装しないと、次の Express エラーが発生します - 500 エラー: ユーザーをセッションにシリアル化できませんでした。それらを実装するとき、デシリアライズに何を入れればよいかわかりません。

以下のコードは機能しているように見えますが、セッションが持続していません。サイトにアクセスするたびにログインする必要があります。

NodeJS + Passport + RedisStore のどこかに良い例はありますか?

var sessionStore = new RedisStore({
                                        host: rtg.hostname,
                                        port: rtg.port,
                                        db: redisAuth[0],
                                        pass: redisAuth[1]
                                      });

passport.use(new ForceDotComStrategy({
    clientID: clientId,
    clientSecret: clientSecret,
    callbackURL: myurl
},
function(token, tokenSecret, profile, done) {
    console.log(profile);
    return done(null, profile);
  }
));

appSecure.configure('production', function(){
appSecure.use(allowCrossDomain);
appSecure.use(express.cookieParser(expressSecret));
appSecure.use(express.bodyParser());
appSecure.use(express.methodOverride());
appSecure.set('port', port); 
appSecure.use(express.session({ secret: expressSecret, store: sessionStore, key:'expressSid', cookie: { maxAge : 604800, domain:'.domain.com'}})); 
appSecure.use(passport.initialize());
appSecure.use(passport.session());
appSecure.use(appSecure.router);
appSecure.use(express.static(__dirname + '/public'));
appSecure.use(express.errorHandler());
});

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

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

3 に答える 3

47

セッションを使用している場合は、パスポートにシリアライズおよびデシリアライズ機能を提供する必要があります。Redis をセッション ストアとして実装することは、パスポートがどのように実装されたかとは関係なく、セッション データが格納される場所のみを扱います。

パスポートを使用したセッションの実装

前述したように、セッションが機能するには、シリアル化および逆シリアル化機能をパスポートに提供する必要があります。

serialize関数の目的は、後続の要求でユーザー アカウントを回復するために十分な識別情報を返すことです。具体的には、done()メソッドの 2 番目のパラメーターは、セッション データにシリアル化された情報です。

提供する逆シリアル化関数は、セッションにシリアル化された識別情報に基づいてユーザー プロファイルを返すことを目的としています。

以下は、セッションについて説明しているセクションのパスポート ガイドの例です。

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

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

上記の例passport.serializeUser()では、ユーザー プロファイル ( user) とコールバック関数 ( done) の 2 つのパラメーターを受け取る関数が提供されています。コールバック関数は、データベースからアカウントを復元するために必要な識別情報 ( user.id、ただし、mongoDB を使用している場合は) を 2 番目のパラメーターとして受け取ります。user._idこれは、認証されたすべてのリクエストで呼び出され、識別情報をセッション データに保存します (Cookie または Redis ストアにあるかどうか)。

passport.deserializeUser()idには、識別情報 ( ) とコールバック関数 ( )の 2 つのパラメーターも受け取る関数が用意されていますdone。識別情報は、前の要求でセッション データにシリアル化されたものです ( user.id)。ここでのコールバック関数は、2 番目のパラメーターとしてユーザー プロファイルを必要とするか、最初のパラメーターとしてプロファイルの取得中に発生したエラーを必要とします。このUser.findById()関数は、データベース内のユーザー プロファイルの検索関数です。この例のオブジェクトは、関数Userを持つマングース モデルのインスタンスです。findById()

に提供される関数は、ユーザー プロファイル ( ) をに格納するルート処理の前にpassport.deserializeUser()、パスポート ミドルウェアによって呼び出されます。passport.session()userreq.user

Redis をセッション ストアとして実装する

Redis を使用する目的は、セッション データをサーバー側に保存することです。したがって、クライアント側に保存される唯一のデータはセッション ID です。繰り返しますが、これはパスポートの実装方法とは無関係です。アプリケーションにセッション サポートを追加している限り、パスポートはセッション データがどこに保存されているかは気にしません。このスタックオーバーフローに関する以前の質問は、 Redis の実装方法に対処しています

于 2013-10-09T22:08:22.350 に答える
13

express-sessionセッション ストアとしてwithを次のように構成しconnect-redisた場合 (Express 4 を使用):

redis = require('redis').createClient(6379, '127.0.0.1');
session = require('express-session');
RedisStore = require('connect-redis')(session);

app.use(session({
  store: new RedisStore({
    client: redis
  }),
  secret: 's3cret',
  resave: true,
  saveUninitialized: true
}));

ユーザーIDだけでなく、ユーザーオブジェクト全体をシリアル化するようにpassportに指示できます。

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

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

ユーザー オブジェクト全体がセッションと共に Redis に保存されreq.user、すべてのリクエストと同様にリクエストに配置されます。

于 2014-10-26T04:43:42.803 に答える