A GET request is triggered simply by visiting a URL. Your browser hits the link, the server responds. Simple.
A POST request, on the other hand, requires a form submission — the user has to actively submit data through a form.
This distinction matters more than it sounds.
The Problem with GET-based Logout
Imagine your logout view is wired to a GET request at /logout. Now imagine a malicious website drops this somewhere in their HTML:
<img src="https://yoursite.com/logout">
When a logged-in user visits that page, their browser dutifully tries to load the "image" — which is actually your logout URL. No click required. No warning. The user is silently logged out without knowing why.
This is called a Cross-Site Request Forgery (CSRF) attack — a malicious site tricks the browser into making a request on the user's behalf.
Why POST Stops This
POST requests can't be triggered by a simple <img> tag or a link. They require a proper form submission. But that alone isn't enough — a malicious site could still craft a hidden form and auto-submit it with JavaScript.
That's where the CSRF token comes in.
What Is a CSRF Token?
Django automatically generates a secret, one-time token and embeds it in every form using the {% csrf_token %} template tag:
<form method="POST">
{% csrf_token %} <!-- Django injects a hidden secret key here -->
...
</form>
This renders in the browser as something like:
<input type="hidden" name="csrfmiddlewaretoken" value="abc123xyz...">
When the form is submitted, Django checks:
- Does this token match what I generated for this session?
- ✅ Yes → legitimate request, process it
- ❌ No → reject it, possible attack
A malicious site has no way to know your token. It's unique per session and never exposed cross-origin. So even if they craft a fake form pointing at your server, the token check will fail and Django will reject it.
The Rule of Thumb
| Action | Method | Why | |---|---|---| | Reading data | GET | Safe, no side effects | | Changing data (login, logout, submit) | POST + CSRF token | Protected from forgery |
Any view that changes state — logging in, logging out, saving a form — should use POST and include Django's CSRF protection. It's a small habit that closes a surprisingly common attack vector.