Cannot use basic authentication while serving static files using express

前端 未结 4 1693
谎友^
谎友^ 2021-02-12 19:29

Using the Express framework for node.js, I\'m trying to serve up static files contained in a directory while also putting basic authentication on it. When I do so, I am prompted

相关标签:
4条回答
  • 2021-02-12 19:47

    app.use doesn't let you chain middlewares in that way. The various app.VERB functions do, but app.use doesn't. That's for one middleware at a time.

    If you split the 2 middlewares out into separate calls, you should get the results you want:

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

    EDIT

    As of express version 4.x you can pass in multiple middlewares as an array, or arguments, or mixture of both into app.use. Making static files authorization safe would now be:

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

    But both ways are still perfectly valid.

    0 讨论(0)
  • 2021-02-12 19:57

    I thought I'd post the express 4 answer here, since there's no other post title as fitting as this one for this specific use-case, and it may be relevant for more people.

    If you're using express 4, chances are you're using serve-index, serve-static, and http-auth (unless there's an easier way that I'm missing out on):

    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 }));
    

    Note, as far as my testing, I didn't need to pass 'authMiddleware' when setting serveStatic.

    0 讨论(0)
  • 2021-02-12 20:03

    Im sharing how it worked out for me.

    app.use("/login", (req, res, next) => {
      if (req.cookies.UUID) {
        res.redirect("/app");
      } else {
        next();
      }
    });
    app.use("/login", express.static("dist_auth_app"));
    app.use("/app", (req, res, next) => {
      if (!req.cookies.UUID) {
        res.redirect("/login");
      } else {
        next();
      }
    });
    app.use("/app", express.static("dist"));
    
    0 讨论(0)
  • 2021-02-12 20:08

    The answer:

    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() }
    }
    

    The 1st app.use() line offers the content of "public" folder in x.x.x.x:4000 ("/" route) to all visitors. The 3rd app.use() line offers the content of "private" folder in x.x.x.x:4000/privatesite ("/privatesite" route) only to user "john" because this line is written after 2nd app.use() line, which loads the authentication middleware. This authentication middleware uses "basic-auth" component, which returns an object with the name and pass written by client. If it is not "john" and "1234", server returns a 401 page; if it is, continue (thanks to next()) to 3rd app.use() line

    0 讨论(0)
提交回复
热议问题