Reputation: 7393
I have a simple form:
{% block content %}
<p> Upload invoices </p>
<form method="post" action="{% url 'upload_thing ' %}" enctype="multipart/form-data">
{% csrf_token %}
<input type="file" name="invoice_thing">
<button type="submit">Upload</button>
</form>
I have a view
@require_POST
@transaction.atomic
def upload_thing(request):
....
How do I make sure that the no one can hit the post endpoint via curl or postman?
I want the end point to be accessible only by hitting the form button. The only people who can do this are admin users.
How do I accomplish this?
Upvotes: 1
Views: 1096
Reputation: 715
The right way to do this in python is via decorators.
from django.contrib.auth.decorators import login_required, user_passes_test
@user_passes_test(lambda user: user.is_superuser)
def upload_thing(request):
In this way you restrict the method and not the html page. So only logged admin can use upload_thing (from curl, postman, or html form).
Upvotes: 0
Reputation: 51998
To be honest, you shouldn't prevent curl or wget requests from django application. It can be done from a reverse proxy server, for example in NGINX you can put the following configuration:
if ($http_user_agent ~* (wget|curl) ) {
return 403;
}
Still, its not a proper protection, User-Agent
information can be spoofed. More information can be found in this serverfault
answer.
If you want to prevent people accessing this page who aren't admin, then you can simply put a restriction on the view like this:
from django.core.exceptions import PermissionDenied
from django.contrib.auth.decorators import login_required
@login_required
@require_POST
@transaction.atomic
def upload_thing(request):
if not request.user.is_superuser:
raise PermissionDenied()
# rest of the code
Upvotes: 1