Невозможно использовать базовую аутентификацию при обслуживании статических файлов с помощью экспресс
Используя фреймворк Express для node.js, я пытаюсь обслуживать статические файлы, содержащиеся в каталоге, а также ставить на него базовую аутентификацию. Когда я это сделаю, мне будет предложено ввести имя пользователя и пароль (как и ожидалось), но после того, как я их правильно введю, мне дается 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
, он обслуживает страницу.
Я использую Express 3.4.7 и node.js 0.10.22.
Ответы
Ответ 1
app.use
не позволяет вам обходить друг друга так. Различные функции app.VERB
выполняются, но app.use
нет. Это для одного промежуточного слоя за раз.
Если вы разделите 2 промежуточных элемента на отдельные вызовы, вы получите желаемые результаты:
app.use('/admin', auth)
app.use('/admin', express.static(__dirname + '/admin'));
ИЗМЕНИТЬ
По сравнению с экспресс-версией 4.x
вы можете передать несколько промежуточных элементов в виде массива или аргументов или их обоих в app.use
. Теперь безопасная авторизация статических файлов будет следующей:
app.use( "/admin", [ auth, express.static( __dirname + "/admin" ) ] );
Но оба пути по-прежнему остаются в силе.
Ответ 2
Ответ:
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 ( "/" ) всем посетителям. Третья строка app.use() предлагает содержимое папки "private" в xxxx: 4000/privatesite ( "/privatesite" ) только пользователю "john", потому что эта строка написана после второй строки app.use(), которая загружает промежуточное программное обеспечение аутентификации. Это промежуточное средство аутентификации использует компонент "basic-auth", который возвращает объект с именем и передачей, написанный клиентом. Если это не "john" и "1234", сервер возвращает страницу 401; если это так, продолжайте (благодаря следующей()) третьей странице app.use()
Ответ 3
Мне показалось, что я опубликую здесь ответ 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 }));
Обратите внимание, что при моем тестировании мне не нужно было передавать "authMiddleware" при установке serveStatic.