简体   繁体   中英

How to serve user specific static content in Express.js

I want to serve user-specific static content in Express. That means, if a user is logged in, his private static folder is served by express. Other users shall not have access.

I tried the following (see below), but the static content is not being served. In fact, the route seems to be completely ignored and I get a 404.

I am not sure if the way I do it is the right way to go and if express is capable of dynamically serving different static folders. Thanks in advance for your thoughts on this.

Here's the code (simplified):

routes.js:

express = require 'express'
router = express.Router()

router.use '/user/assets', (req, res, next) ->
    if req.user
        userpath = 'uploads/' + md5(req.user._id)
        if not fs.existsSync userpath
            fs.mkdirSync userpath
            console.log "Created user directory at " + userpath

        express.static(userpath)
    next()

module.exports = router

index.js:

express = require 'express'
app = express()
app.use '/', require './routes'

Sidenotes :

The md5 is just a way of escaping weird characters in the user id, which is a string. I know there is a possibility for a mismatch, which is tiny, and about which I don't wanna care for now. Concerns about general security of the fashion of the solving attempt are appreciated. The code is written in CoffeeScript.

req.user contains a valid user element.

Just calling express.static is not enough, you need to use() it with the router. Unfortunately you can't directly do that, since you require a different set of routes for each user.

Calling express.static will return a middleware function. You could call it directly, ie something like this:

var files = express.static(userpath);
return files(req, res, next);

However that's still not enough, as the middleware uses req.url to build the file path. The express router adjusts this property and removes the mount point (see req.originalUrl in the docs). So you need to strip /user/assets from it, before calling the middleware.

By the way, you should set the DEBUG environment variable for node. It allows you to see what routes are created by express, which is very handy in debugging express.static 404 problems. Eg you'd do $ DEBUG=* node index.js on Linux.

As you can see the approach starts to be a bit hacky and creating a new express.static middleware on each request is not very performance friendly too. So depending on what your user directories contain, using res.sendFile might actually be better.

As a sidenote, I assume you've checked that req.user actually contains something if the user is logged in.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM