I'm creating a website where the user is able to upload large files. Around 100-300Mb. I'm using django but I want to know what is the best option to save the files. Should I just add them to my user database? Or should I create a media folder and save the files there. If so then this would mean that I have to save the name of the file in my user database?
Please let me know how you would tackle this issue.
django does not store files in the database, but in media folder. The FileField contains the path to the file(in the media folder). You can change that behavior but it is not recommended(as general practice). What you should consider however is that files of that size will require some more work both in django and the front-end since the upload process will freeze the server. A potential solution to the problem is this: https://pypi.org/project/django-chunked-upload/
Related
I've looked over the questions in SO and none can explain the proper usage of Django's FilePathField. The Django documentation about it is a little short. A web search does not yield good tutorials about it as well. To add do non uploaded files must be collected to the static directory,reside inside apps where they are used, or at the project level?
If you want to handle uploaded files consider using FileField instead of FilePathField. FileField also stores path to the uploaded file, but it is designed to handle new file creation for uploads. FilePathField is just used to point to a path in your file system.
I am providing sensitive username and password file to the authenticated user. I want user to download the file via file_url in template through model.
File_link = models.FileField(upload_to='SAFE_DIRECTORY_PATH')
I don't feel it safe storing it in media directory
Any suggestions keeping them safe ,web app will be generating the link.
Some security notes first.
This is probably a bad idea. Storing sensitive information in plain files is probably not the correct security approach, especially if you plan to use Django's media storage backend for doing that. It leaves all files out-in-the-open.
If however you really, really, and I mean really need to do that, you should encrypt the file first before saving in Django.
Again though, if at all possible I would recommend to store sensitive information in db. In your case of storing passwords, you can use Django techniques to store that information relatively-safely such as correctly hashing passwords via pbkdf function (e.g. pbkdf or bcrypt, etc). If users will need to download that information, you can always generate the file on the fly for them for download.
Some suggestions for uploading files.
I usually assign random filenames to the uploaded files. This way at least its more challenging for the users to guess the filenames to download them. Not very security since this relies on security by obfuscation but its better then nothing. If you need a Django field which does that automatically, you can do that by making upload_to a callable (there are also 3rd party libs for doing that such as django-auxilium although for full disclosure Im the author of that lib).
Now that files are stored with random filenames, you probably never want to provide direct download links to the users for download but instead authenticate them first and then use something like X-Accel in nginx or X-Sendfile in Apache to actually serve the file to the user. The idea being that you first authenticate user in Django. Then however instead of Django serving the file, you return a special header which nginx/apache catches which contains a filepath to the file nginx/apache should serve to the user. This way you dont have to waste resources in Django to serve the file however you still get the advantage of being able to authenticate the request. There are a number of 3rd party apps for doing that as well.
Finally to protect users from downloading the media files you can use nginx (and I imagine apache) by restricting certain parts of the media folder:
location /media/protected {
internal;
alias /var/www/files;
}
In this case nginx will refuse direct user requests to /media/protected and will only allow to serve those files via X-Accel-Redirect header sent by Django. Then all you have to configure in Django is to store files in that path to make them protected:
models.FileField(upload_to='protected/myfiles')
I was looking for a solution to serve files only to authorized users and came across this post. I think it it is top google result for "django storing and providing secure files"
As the answer is rather old I wanted to share my finding:
django-private-storage (https://pypi.org/project/django-private-storage/) seems to be a good solution to this problem.
I am making a django application that makes user of django's ImageField to upload a file to a specific folder. I am using this field for storing the user's profile pictures. But the problem is the path that I give to upload_to is dynamic and depends on user and will create directories if needed. i.e if the path is user/1/profile-pic/large/pic.jpg, it will create the directores, user/, user/1/ so on, if the are not already there. It worked fine in development. But now when I have put my website on a VM and serving it using apache. Django raises the permission denied error. As I have to make directories dynamically so I can't make them ahead of everything and change their permissions. So I was wondering if there is any of way of acoomplishing it.
You should chown you media directory to the user which runs you django app.
I have a situation where I have a Django app where users sign up for an account. The users generate a bunch of Excel files each month. These files are currently simply files generated on the server and stored in the filesystem, and are not part of any model definition right now, though I could probably change that to have them defined in a model, and use together with user permissions.
The app is working as expected, but I am stuck on how to let users browse and download their own generated files, while disallowing access to other users' files.
I was looking at django-filer, but am wondering if anybody has met with this situation before?
You'll want a FileField, a FK or M2M to User or Group, and this.
My Django site lets users upload images. It's running on Apache.
Files are uploaded via a FileUpload form. The folder to which files are uploaded is outside the Django project, and protected as described here, i.e. the folder has 755 permissions and files have 644 permissions.
I now want to serve the images up to users - but I need to do it securely, so that executable scripts don't run, and so that users can't e.g. delete all the images in the directory.
My question is, how do I serve the uploaded images to users in a secure way? Can I serve them safely as static media directly from that folder, with those permissions? Or should I copy them into another directory with different permissions, and serve them from there?
I'm serving the other static media (/media/css) on the site as a separate, static application.
Thanks!
The way to do this is to configure your web server to serve files with the names it expects, and with a correct image content-type. Use Django's ImageField for some level of validation by PIL/Pillow that uploaded files are images. For this directory, disable webserver features like autogenerating directory indexes, autoserving everything from the filesystem, guessing at mime types, and running cgi scripts.