首页 文章

使用express提供静态文件时无法使用基本身份验证

提问于
浏览
14

使用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 时,它会提供页面 .

我正在使用Express 3.4.7和node.js 0.10.22 .

3 回答

  • 0

    app.use 不允许您以这种方式链接中间件 . 各种 app.VERB 函数都可以,但是 app.use 一次只能为一个中间件做't. That' .

    如果将2个中间件拆分为单独的调用,则应获得所需的结果:

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

    EDIT

    从快递版本 4.x 开始,您可以将多个中间件作为数组或参数或两者的混合传递到 app.use 中 . 现在,使静态文件授权安全:

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

    但这两种方式仍然完全有效 .

  • 4

    答案:

    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(“/”route)中“public”文件夹的内容 . 第3个app.use()行仅向用户“john”提供xxxx:4000 / privatesite(“/ privatesite”路由)中“private”文件夹的内容,因为此行是在第二个app.use()行之后写入的,加载身份验证中间件 . 此身份验证中间件使用“basic-auth”组件,该组件返回具有名称和客户端写入的传递的对象 . 如果不是“john”和“1234”,则服务器返回401页面;如果是,继续(感谢next())到第3个app.use()行

  • 30

    我以为我会在这里发布快递4回答,因为没有其他帖子 Headers 适合这个特定用例,这可能与更多人有关 .

    如果您正在使用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' .

相关问题