web-dev-qa-db-ja.com

エクスプレスで各ルートを入力する前に、ミドルウェアを使用して承認を確認する方法は?

ユーザーがURLを入力したときに、Webアプリのユーザーの承認を確認したい。ただし、個別にミドルウェアを使用して認証を確認した場合、次のような既存のルートには役に立たない:

function authChecker(req, res, next) {
    if (req.session.auth) {
        next();
    } else {
       res.redirect("/auth");
    }
}

app.use(authChecker);
app.get("/", routes.index);
app.get("/foo/bar", routes.foobar);

authCheckerは、2つのURLを入力したユーザーの権限を確認できません。指定されていないURLに対してのみ機能します。

そして、私はauthCheckerをルートとルートハンドラーの間に置くことができるメソッドを見ました:

app.get("/", authChecker, routes.index);

しかし、すべてのルートにauthCheckerを配置するのではなく、簡単な方法でそれを達成するにはどうすればよいですか?

32
Noah Blues

限り

app.use(authChecker);

前です

app.use(app.router);

リクエストごとに呼び出されます。ただし、/ authを含むALL ROUTESで呼び出されるため、「too many redirects」を取得します。そのため、これを回避するには、関数を次のように変更することをお勧めします。

function authChecker(req, res, next) {
    if (req.session.auth || req.path==='/auth') {
        next();
    } else {
       res.redirect("/auth");
    }
}

この方法では、認証URLもリダイレクトされません。

32
guydog28

この問題に対処する方法はいくつかありますが、ここで私に役立つものを紹介します。

保護されたルートと保護されていないルート用のミドルウェアの配列を作成し、必要なときに使用します。

var protected   = [authChecker, fetchUserObject, ...]
var unprotected = [...]

app.get("/", unprotected, function(req, res){
  // display landing page
})

app.get("/dashboard", protected, function(req, res){
  // display private page (if they get this far)
})

app.get("/auth", unprotected, function(req, res){
  // display login form
})

app.put("/auth", unprotected, function(req, res){
  // if authentication successful redirect to dashboard
  // otherwise display login form again with validation errors
})

これにより、各タイプのルートの配列を編集することにより、各ミドルウェアスコープの機能を簡単に拡張できます。また、ルートの種類を示すため、各ルートの機能がより明確になります。

お役に立てれば。

24
sintaxi

しかし、承認を確認するために個別のミドルウェアを使用した場合、既存のルートには役に立たない

Expressは、スタックに追加された順序でミドルウェアを実行します。ルーターは、これらのミドルウェア機能の1つです。 authCheckerをルーターの前にスタックに入れる限り、すべてのルートで使用され、動作します。

ほとんどの場合、authCheckerをスタックに入れる前にルートが定義されているため、authCheckerの前にルーターがあります。 app.useapp.getなどの呼び出しの前に、すべてのapp.post呼び出しを配置し​​て、Expressによるルーターのミドルウェアスタックへの暗黙のインジェクションを回避してください。

1
Peter Lyons