Как обслуживать пользовательский статический контент в Express.js

Я хочу предоставлять статический контент для конкретного пользователя в Express. Это означает, что если пользователь вошел в систему, его личная статическая папка обслуживается экспресс. Другие пользователи не должны иметь доступа.

Я попробовал следующее (см. ниже), но статическое содержимое не обслуживается. На самом деле маршрут полностью игнорируется, и я получаю 404.

Я не уверен, что то, как я это делаю, является правильным, и если экспресс способен динамически обслуживать разные статические папки. Заранее спасибо за ваши мысли по этому поводу.

Вот код (упрощенный):

маршруты.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'

Примечания:

md5 — это просто способ избежать странных символов в идентификаторе пользователя, который является строкой. Я знаю, что есть вероятность несоответствия, которое ничтожно мало и о котором я не хочу сейчас заботиться. Приветствуются опасения по поводу общей безопасности способа решения. Код написан на CoffeeScript.

req.user содержит допустимый пользовательский элемент.


person Flaudre    schedule 27.11.2016    source источник


Ответы (1)


Просто позвонить express.static недостаточно, нужно use() с роутером. К сожалению, вы не можете сделать это напрямую, так как вам требуется разный набор маршрутов для каждого пользователя.

Вызов express.static вернет промежуточную функцию. Вы можете вызвать его напрямую, т.е. что-то вроде этого:

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

Однако этого все же недостаточно, так как промежуточное ПО использует req.url для построения пути к файлу. Экспресс-маршрутизатор настраивает это свойство и удаляет точку подключения (см. req.originalUrl). в документах). Поэтому вам нужно удалить из него /user/assets перед вызовом промежуточного программного обеспечения.

Кстати, вы должны установить переменную окружения DEBUG для node. Это позволяет вам видеть, какие маршруты создаются экспрессом, что очень удобно при отладке проблем express.static 404. Например. вы бы сделали $ DEBUG=* node index.js в Linux.

Как вы можете видеть, подход начинает быть немного хакерским, и создание нового промежуточного программного обеспечения express.static для каждого запроса также не очень благоприятно для производительности. Таким образом, в зависимости от того, что содержится в ваших пользовательских каталогах, использование res.sendFile на самом деле может быть лучше.

В качестве примечания я предполагаю, что вы проверили, что req.user действительно что-то содержит, если пользователь вошел в систему.

person svens    schedule 27.11.2016
comment
Большое спасибо! res.sendFile был именно тем, что я искал. В противном случае это действительно окажется хакерским. - person Flaudre; 27.11.2016