37

Webアプリケーションのセッションの概念を理解するのに助けが必要です。Express3.0でNode.jsサーバーを実行しています。

私の目標は次のとおりです。

  • ログインするユーザーごとにセッションを作成します

  • このセッションを保存し、ユーザーがすでにログインしているかどうかを検証し(2つのデバイスが同じユーザーを同時に使用しないようにする)、特定のページへのアクセスを制限する(セッションIDを他のデータと照合する)ために使用します

私はMemoryStoreを使用してセッションを保存します(最も簡単なようです)。上記の目標が理にかなっている場合、それらを達成する方法の完全な説明を提供できますか?

4

2 に答える 2

42

Expressのgithubリポジトリには良い例があります。それらの1つは認証を扱い、ユーザーをreq.sessionオブジェクトにアタッチする方法を示します。これはapp.post('/login')ルート内で行われます。

特定のページへのアクセスを制限するには、それらのルートに単純なミドルウェアを追加します

function restrict(req, res, next) {
  if (req.session.user) {
    next();
  } else {
    req.session.error = 'Access denied!';
    res.redirect('/login');
  }
}

app.get('/restricted', restrict, function(req, res){
  res.send('Wahoo! restricted area, click to <a href="/logout">logout</a>');
});

Brandonがすでに述べたように、本番環境ではMemoryStoreを使用しないでください。Redisは良い代替手段です。connect-redisを使用してデータベースにアクセスします。設定例は次のようになります

var RedisStore = require('connect-redis')(express);

// add this to your app.configure
app.use(express.session({
  secret: "kqsdjfmlksdhfhzirzeoibrzecrbzuzefcuercazeafxzeokwdfzeijfxcerig",
  store: new RedisStore({ host: 'localhost', port: 3000, client: redis })
}));
于 2013-01-08T22:15:09.033 に答える
10

複数のインスタンスを作成していない場合(クラスターモジュールなど)にのみ、ExpressでMemoryStoreを使用してください。マシン間で負荷分散を行う場合、ロードバランサーはスティッキー/永続セッションを使用する必要があります。

これらの要件を満たしている場合は、ログイン時に行う必要があるのは、資格情報が検証されたら、ログインを示すセッション変数を設定することです。次に例を示します。

req.session.loggedIn = true;

ユーザーがログインしているかどうかを確認する場合は、その変数を確認するだけです。

if (req.session.loggedIn) {
    // user is logged in.
}
else {
    // user is not logged in.
}

1人のユーザーが一度に複数のセッションを持つことを防ぐとおっしゃいました。これを実現するには、ユーザーがログインしていることを示す何かをデータベースに保存する必要がある場合があります。これは、古いセッションのために危険な場合があることを警告します。たとえば、ユーザーがログインしてもログアウトしない場合はどうなりますか?彼らがブラウザウィンドウを閉じて、セッションが永久に終了した場合はどうなりますか?

Expressには、アイドルセッションの有効期限の概念はありません。私は、最後にアクセスしたタイムスタンプとともにすべてのセッションをデータベースに保存し、時間に基づいてセッションデータを定期的にクリーンアップすることで、このようなことを実装しました。ただし、ログインしているユーザーのリストも更新する必要があります。

于 2013-01-08T19:35:05.473 に答える