web-dev-qa-db-ja.com

Expressを使用して静的ファイルを提供している間は基本認証を使用できません

Node.js用のExpressフレームワークを使用して、ディレクトリに含まれる静的ファイルを提供すると同時に、基本認証を適用しようとしています。そうすると、(期待どおりに)ユーザー名とパスワードの入力を求められますが、正しく入力すると404が表示されます。認証チェックを削除して同じディレクトリを提供すると、実際にページが表示されます。その中に含まれています。

これは、概念実証として作成したクイックサーバーです。

var express = require('express');

var app = express();

var auth = express.basicAuth(function(user,pass) {
  return 'user' === user && 'pass' === pass;
});

app.use('/admin', auth, express.static(__dirname + '/admin'));
app.use('/adminNoAuth', express.static(__dirname + '/admin'));

app.listen(8082);

localhost:8082/adminを押すと、ユーザー名/パスワード、次に404が表示されます。localhost:8082/adminNoAuthを押すと、ページが表示されます。

Express3.4​​.7とnode.js0.10.22を使用しています。

17
CanSpice

app.useでは、ミドルウェアをそのようにチェーンすることはできません。さまざまなapp.VERB関数は機能しますが、app.useは機能しません。これは、一度に1つのミドルウェア用です。

2つのミドルウェアを別々の呼び出しに分割すると、必要な結果が得られるはずです。

app.use('/admin', auth)
app.use('/admin', express.static(__dirname + '/admin'));

[〜#〜]編集[〜#〜]

エクスプレスバージョン4.x以降、複数のミドルウェアを配列、引数、または両方の組み合わせとしてapp.useに渡すことができます。静的ファイルの認証を安全にするには、次のようになります。

app.use( "/admin", [ auth, express.static( __dirname + "/admin" ) ] );

しかし、どちらの方法も完全に有効です。

36
juanpaco

答え:

var express = require("express")
var ss = require("serve-static")
var ba = require("basic-auth")
var app = express()
app.use("/", ss(__dirname + "/public"))
app.use(entry)
app.use("/privatesite", ss(__dirname + "/private"))
app.listen(4000)  

function entry(req, res, next) {
    var objUser = ba(req)
    if (objUser === undefined || objUser.name !== "john" || objUser.pass !== "1234") {
        res.set("WWW-Authenticate", "Basic realm=Authorization Required")
        res.status(401).end()
    } else { next() }
}

最初のapp.use()行は、x.x.x.x:4000( "/"ルート)の "public"フォルダーのコンテンツをすべての訪問者に提供します。 3番目のapp.use()行は、xxxx:4000/privatesite( "/ privatesite"ルート)の「private」フォルダーのコンテンツをユーザー「john」にのみ提供します。これは、この行が2番目のapp.use()行の後に記述されているためです。認証ミドルウェアをロードします。この認証ミドルウェアは、「basic-auth」コンポーネントを使用します。このコンポーネントは、クライアントによって書き込まれた名前とパスを持つオブジェクトを返します。 「john」と「1234」でない場合、サーバーは401ページを返します。そうである場合は、(next()のおかげで)3番目のapp.use()行に進みます

4
Osqui

この特定のユースケースにこれほど適した投稿タイトルは他になく、より多くの人に関連する可能性があるため、ここにエクスプレス4の回答を投稿すると思いました。

Express 4を使用している場合は、serve-index、serve-static、およびhttp-authを使用している可能性があります(私が見逃しているより簡単な方法がない限り)。

serveIndex = require('serve-index'),
serveStatic = require('serve-static'),
auth = require('http-auth');     

// Basic authentication
var basic = auth.basic({
        realm: "My Secret Place.",
    }, function (username, password, callback) { // Custom authentication method.
        callback(username === "me" && password === "mepassword");
    }
);

var authMiddleware = auth.connect(basic);

// Serve /secretplace as a directory listing
app.use('/secretplace', authMiddleware, serveIndex(__dirname + '/public/secretplace'));

// Serve content under /secretplace as files
app.use('/secretplace', serveStatic(__dirname + '/public/secretplace', { 'index': false }));

私のテストに関する限り、serveStaticを設定するときに「authMiddleware」に合格する必要はなかったことに注意してください。

0
ykay