1. Introduction
Each document has to be seen only by the owner. When you open the dashboard, you only see the documents you created. And you click one of your documents. Now you go to another URL and you can see the document. But after logging out, you can enter the URL, and you can still see the document. That is, anybody who knows the document's URL can access the document. This is contrary to the statement that each document has to be seen only by the owner. How can I solve this problem?
2. The Problem
I found that even if you don't log in, you can see all the documents if you know the URL. For example, a user Jim's document is at
https://myid.pythonanywhere.com/media/client_documents/11.png
and anyone can see the document if they know this URL. How can I prevent the document from being seen by outsiders?
Great catch 👍 — that’s a very important security issue.
What’s happening is this:
-
Right now, your uploaded files (like
client_documents/11.png) are being stored under/media/and served directly by Django/your web server. -
By default,
/media/is public — so anyone who knows the URL can fetch the file, even if they are not logged in.
That’s why Jim’s document is accessible without login.
🔒 How to protect media files in Django
There are two common approaches:
1. Store files in /media/ but serve them through a protected view
Instead of letting the web server serve /media/ directly, you:
-
Configure Django so that
/media/client_documents/is not public. -
Write a Django view that:
-
Checks if the user is logged in (and/or is the file’s owner).
-
If allowed, reads the file and returns it via
FileResponse. -
If not allowed, returns a
403 Forbidden.
-
Example:
Then in urls.py:
✅ Now, instead of linking directly to /media/client_documents/11.png,
you link to /documents/11/ (your protected view).
Only the owner can access it.
2. Store files outside /media/
-
Move uploaded files to a folder outside the web-accessible directory.
-
Only serve them through the protected view above.
For example:
instead of /home/yourusername/myproject/media/.
That way, outsiders cannot type a URL to guess the file.
3. (Optional Advanced) Use cloud storage with signed URLs
If you ever use S3, Google Cloud Storage, etc., you can generate temporary signed URLs that expire quickly.
This way, even if someone copies the URL, it won’t work after e.g. 5 minutes.
✅ Quick fix for you now:
-
Change your file links to go through a Django view (
protected_document). -
Restrict access in that view with
login_requiredand ownership checks. -
Don’t serve sensitive files directly from
/media/.
👉 Do you want me to show you how to reconfigure your settings.py and urls.py so /media/ is no longer public and everything goes through a secure view?
3. Hide uploaded documents
You can hide uploaded documents if you set in settings.py:
DEBUG = False
This will make /media/ no longer public, but you may need to set in settings.py:
STATIC_URL = '/static/'
STATIC_ROOT = BASE_DIR / 'staticfiles'
And you may need to run:
python manage.py collectstatic
4. How to access uploaded documents
To make the app access uploaded documents, I added the following code to views.py:
from django.http import FileResponse, Http404
# New protected document download view
@login_required
def download_document(request, doc_id):
try:
document = ClientDocument.objects.get(id=doc_id, owner=request.user)
except ClientDocument.DoesNotExist:
raise Http404("Document not found or not yours")
return FileResponse(document.file.open('rb'))
And I added the following code to urls.py:
path("documents/<int:doc_id>/download/", views.download_document, name="download_document"),
And I changed the old link to a new link in dashboard.html:
<!-- old link
<li><a href="{{ doc.file.url }}">{{ doc.file.name }}</a></li> -->
<!-- new link -->
<li><a href="{% url 'client_portal:download_document' doc.id %}">{{ doc.file.name }}</a>
