Примечание: для всех этих примеров я использую приложение со следующей структурой:
.
├── 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!
Проблема с этим подходом заключается в том, что запрос должен пройти весь путь через маршрутизатор вашего приложения, прежде чем статический файл может быть обслужен, что не так эффективно, но может подойти для ваших нужд (вам нужно будет принять некоторые замеры и узнайте сами).
Другой вариант — вставить небольшую функцию в цепочку промежуточного программного обеспечения, которая делает в основном то же самое, но не требует прохождения через весь маршрутизатор приложения:
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!
person
Michelle Tilley
schedule
11.08.2012