所以首先你應該使用fs.mkdir
爲每個用戶創建一個文件夾:
http://nodejs.org/api/fs.html#fs_fs_mkdir_path_mode_callback
比方說,你要創建這些文件夾到你的應用程序根/圖片:
例子:
var fs = require('fs');
fs.mkdir(__dirname + '/images/' + userId, function(err) {
if (err) {
/* log err etc */
} else {
/* folder creation succeeded */
}
});
您應該使用userId
作爲文件夾名稱(因爲它很簡單而不是試圖從用戶名本身去掉不好的字符,並且如果用戶改變他的用戶名,這也將在未來工作)。
您需要做的第二件事是允許用戶上傳文件(但只有當他登錄並進入正確的文件夾時)。最好是不包括bodyParser
中間件爲所有路由,而是包括所有路由json
& & urlencoded
中間件(http://www.senchalabs.org/connect/json.html & & http://www.senchalabs.org/connect/urlencoded.html),並只對上傳的URL multipart
中間件(http://www.senchalabs.org/connect/multipart.html & &例如:https://github.com/visionmedia/express/blob/master/examples/multipart/index.js)。
一個例子:
app.post('/images', express.multipart({ uploadDir: '/tmp/uploads' }), function(req, res, next) {
// at this point the file has been saved to the tmp path and we need to move
// it to the user's folder
fs.rename(req.files.image.path, __dirname + '/images/' + req.userId + '/' + req.files.image.name, function(err) {
if (err) return next(err);
res.send('Upload successful');
});
});
注:在上面的例子中我已經考慮到req.userId
填充與用戶的通過一個auth中間件的ID。
顯示的圖像給用戶,如果他有權利看到他們(AUTH中間件應適用於這條道路以及):
app.get('/images/:user/:file', function(req, res, next) {
var filePath = __dirname + '/images/' + req.userId + '/' + req.params.file;
fs.exists(filePath, function(exists) {
if (!exists) { return res.status(404).send('Not Found'); }
// didn't attach 'error' handler here, but you should do that with streams always
fs.createReadStream(filePath).pipe(res);
});
});
注:在生產中,你可能要使用send代替,那個例子只是演示流程(https://github.com/visionmedia/send)。
使用['fs.exists'](http://nodejs.org/api/fs.html#fs_fs_exists_path_callback),['fs.mkdir'](http://nodejs.org/api/fs.html #fs_fs_mkdir_path_mode_callback)以及['fs.createWriteStream'](http://nodejs.org/api/fs.html#fs_fs_createwritestream_path_options)或['fs.write']之一(http://nodejs.org/api/ fs.html#fs_fs_write_fd_buffer_offset_length_position_callback)。一定要測試我不能寫例如'../../../../ ../ etc/passwd',因爲這對你的站點的安全性來說會非常糟糕 – Plato
某人如何能夠通過我的webapp寫這個文件?我認爲文件可以上傳的目錄是由我控制的? – Swarage
例如如果你允許他們設置文件名,可以將其命名爲'/ your/directory/theirfolder /../../../../../etc/passwd'。我不確定你必須採取哪些步驟,如果有的話,擦除這樣的文件名。爲了安全起見,我會將它命名爲隨機,並且保持(硬盤驅動器上的文件名)與(在密碼箱中顯示的對象的名稱) – Plato