注:これらすべての例では、次のような構造のアプリケーションを使用しています。
.
├── app.js
└── public
├── protected
│ └── file.txt <-- contains text "protected file"
└── regular
└── file.txt <-- contains text "regular file"
いくつかのオプションがあります。最も簡単な方法は、Expressがパブリックミドルウェアの前にルーターを介してリクエストをルーティングし、リクエストをインターセプトできるようにすることです。
var express = require('express');
var http = require('http');
var path = require('path');
var app = express();
// use app.router before express.static
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
function userIsAllowed(callback) {
// this function would contain your logic, presumably asynchronous,
// about whether or not the user is allowed to see files in the
// protected directory; here, we'll use a default value of "false"
callback(false);
};
app.get('/', function(req, res, next) {
res.end('Home page');
});
app.get('/protected/*', function(req, res, next) {
userIsAllowed(function(allowed) {
if (allowed) {
next(); // call the next handler, which in this case is express.static
} else {
res.end('You are not allowed!');
}
});
});
http.createServer(app).listen(3000, function(){
console.log('Express server listening on port 3000');
});
結果:
http://localhost:3000/regular/file.txt # regular file
http://localhost:3000/protected/file.txt # You are not allowed!
このアプローチの問題は、静的ファイルを提供する前に、リクエストがアプリのルーターを完全に通過する必要があることです。これはそれほど効率的ではありませんが、ニーズには問題ない場合があります(測定して自分で調べてください)。
もう1つのオプションは、基本的に同じことを行う小さな関数をミドルウェアチェーンに挿入することですが、アプリルーター全体を実行する必要はありません。
var express = require('express');
var http = require('http');
var path = require('path');
function userIsAllowed(callback) {
// this function would contain your logic, presumably asynchronous,
// about whether or not the user is allowed to see files in the
// protected directory; here, we'll use a default value of "false"
callback(false);
};
// This function returns a middleware function
var protectPath = function(regex) {
return function(req, res, next) {
if (!regex.test(req.url)) { return next(); }
userIsAllowed(function(allowed) {
if (allowed) {
next(); // send the request to the next handler, which is express.static
} else {
res.end('You are not allowed!');
}
});
};
};
var app = express();
app.use(protectPath(/^\/protected\/.*$/));
app.use(express.static(path.join(__dirname, 'public')));
app.get('/', function(req, res, next) {
res.end('Home page');
});
http.createServer(app).listen(3000, function(){
console.log('Express server listening on port 3000');
});
これは基本的に同じロジックを実行しますが、アプリルーター全体を介してすべてのリクエストをルーティングする代わりに、リクエストされたURLが渡された正規表現と一致するかどうかを確認する小さな関数を各リクエストの開始時に実行します。チェックを実行して、ユーザーがファイルにアクセスできるかどうかを確認します。
結果:
http://localhost:3000/regular/file.txt # regular file
http://localhost:3000/protected/file.txt # You are not allowed!