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, i.e. 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. E.g. 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.