使用快递服务静态文件时,不能使用基本身份validation

使用Node.js的Express框架,我试图提供包含在一个目录中的静态文件,同时也把基本的身份validation。 当我这样做时,我被提示input用户名和密码(如预期的那样),但是在我正确地input它们之后,我得到了一个404。如果我删除身份validation检查并提供相同的目录,我实际上得到页面包含在其中。

这是一个我作为一个概念validation的快速服务器:

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。

app.use不会让你以这种方式链接中间件。 各种app.VERBfunction,但app.use不。 这是一次一个中间件。

如果将两个中间件拆分为不同的调用,则应该得到所需的结果:

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

编辑

从express版本4.x您可以将多个中间件作为数组或参数或者两者的混合formsapp.useapp.use 。 现在,使静态文件授权安全:

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

但是这两种方式仍然是完全有效的。

答案:

 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()行向所有访问者提供xxxx:4000(“/”路由)中的“public”文件夹的内容。 第三个app.use()行在xxxx:4000 / privatesite(“/ privatesite”路由)中仅将“private”文件夹的内容提供给用户“john”,因为该行在第二个app.use()行之后写入,加载authentication中间件。 这个authentication中间件使用“basic-auth”组件,它返回一个名字对象,并由客户端写入。 如果不是“john”和“1234”,则服务器返回一个401页面; 如果是,继续(感谢next())到第三个app.use()行

我以为我会在这里发表快速答案,因为这个具体的用例没有其他的post标题,可能与更多的人有关。

如果你使用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 })); 

请注意,就我的testing而言,在设置serveStatic时,我不需要传递“authMiddleware”。