For those following trunk, the CSRF changes have now landed (apart
from Simon's proposed refinements).
At first I thought this would be perfectly seamless, not requiring any
immediate action, and it therefore didn't warrant a note to django-
devs. However, there are circumstances when developers MUST update
their code immediately to avoid breakage.
If you have supplied custom templates to contrib views that accept
POST requests (e.g. auth login etc.), the template may need updating.
The steps needed are fully described in the docs, but in short:
Inside all <form method="POST"> elements, add {% csrf_token %}
That's it. Apologies to anyone who has already experience breakage
because of this.
This brings up another question - I don't know what our policy for
backwards compatibility with respect to templates is. Obviously if
you completely override an entire template for something like an admin
page, you cannot expect everything to keep working — otherwise it
would be impossible to add any new features to the admin. Also there
is the problem of inheritance etc. — do we guarantee that the
inheritance/include chain of all blocks will stay the same? Sometimes
you need to move anything around — 'refactor' if you will — and a
commitment not to change anything here would be painful (and it's not
what we've done so far, although we have minimized unnecessary
changes).
How much do we consider those who have overridden templates by setting
TEMPLATE_DIRS so that a custom template (e.g. admin/base_site.html) is
chosen over the default one? It's a common pattern, although in some
ways it could be considered a hack.
Is it different for views that have explicit hooks for customisation
(like a template_name keyword argument)? For the latter, I think the
view function docstring should document everything that will be in the
template context if we are making guarantees about compatibility. But
that would not have avoided the current problem of needing to insert
something extra.
What about CSS/javascript? I know there have been a number of changes
here which have caused breakage if people have overridden templates in
certain ways, but it seems unreasonable to require the admin CSS to
remain organized as it is now. The docs for this are in slight
disarray — I can only find some obsolete docs which say that they
don't apply any more.
It's actually quite hard to define backwards compatibility in this
area, much more so than with Python code.
Luke
--
Environmentalists are much too concerned with planet earth. Their
geocentric attitude prevents them from seeing the greater picture
-- lots of planets are much worse off than earth is.
Luke Plant || http://lukeplant.me.uk/
> If you have supplied custom templates to contrib views that accept
> POST requests (e.g. auth login etc.), the template may need updating.
> The steps needed are fully described in the docs, but in short:
>
> Inside all <form method="POST"> elements, add {% csrf_token %}
>
> That's it. Apologies to anyone who has already experience breakage
> because of this.
And there are also some typos in guide:
====================================
http://docs.djangoproject.com/en/dev/ref/contrib/csrf/#legacy-method
====================================
In Django 1.1, the template tag did not exist. Instead, a post-
processing middleware that re-wrote POST forms to include the CRSF
token was used.
Use of the CsrfResponseMiddleware is not recommended because of the
performance hit it imposes, and because of a potential security
problem (see below). It can be used as an interim measure until
applications have been updated to use the {% crsf_token %} tag. It is
deprecated and will be removed in Django 1.4.
====================================
Typos:
... POST forms to include the CRSF token was used.
It should say "the CSRF token was used." and it's not {% crsf_token %}
but {% csrf_token %}
Davor
> And there are also some typos in guide:
Cheers! Fixed now. After this patch, I won't be sad if I never have
to type 'csrf' (or 'crsf') ever again :-) But unfortunately I will...
The CSRF protection is enabled by default in MIDDLEWARE_CLASSES, for
the unlikely scenario that you haven't set that setting. This is as
documented.
It is also enabled for all contrib views, as documented. That can
break if you using views from contrib apps, and have supplied custom
templates which don't have the CSRF token.
Beyond that, I'll need more details!
> If you have supplied custom templates to contrib views that accept
> POST requests (e.g. auth login etc.), the template may need
> updating. The steps needed are fully described in the docs, but in
> short:
>
> Inside all <form method="POST"> elements, add {% csrf_token %}
>
> That's it.
It looks like this doesn't work for templates that are rendered by
inclusion_tag(). That's because they don't inherit the context —
something I didn't realise (probably because I haven't used
inclusion_tag).
There is a patch on http://code.djangoproject.com/ticket/12095 that
tries to address this.
I think the best solution is to fix inclusion_tag, rather than require
any complex changes for developers — otherwise they will get fed up
and decide "Django's CSRF sucks" and not use it. A nicer and more
general way of fixing inclusion_tag would be welcome. Adding tests
for this is a bit of a pain due to the way custom template tag
libraries need to be in an 'app'.
Repeating what I said on #django-dev this morning, I'm +1 on this
patch. Rending forms via an inclusion tag is a pretty common pattern
[1], and we shouldn't break it. I'm just fine special-casing the CSRF
token in inclusion_tag.
Jacob
[1] At least a couple of Django training programs, including the ones
I do, teach this technique. It's also in at least one book.
I'm not sure how wide spread this will become, but I think for new
users it could be a problem. When asked what version of the doc he was
using he replied the one for trunk. He is running trunk but he did not
svn up for a few days hence his trunk falling behind.
Im not sure the best way to combat this problem, it was easily spotted
by me but only because I follow this list. Maybe the problem is people
that are learning should not be learning on trunk, which probably goes
without saying.
Anyways just thought I'd drop a real life user story seeing how this
feature just landed.
- Sean
You should read:
http://docs.djangoproject.com/en/dev/ref/contrib/csrf/#upgrading-notes
Also, this is list is not for general Django troubleshooting but
rather for Django development.
Davor
The token doesn't affect it directly. The HttpRequest class that
TestCase uses is hacked so that the middleware and csrf_protect
decorator don't actually reject requests which have the token.
Basically, it disables the protection for your tests, to make testing
of views much easier. All the cookies and tokens work just the same.
Luke
--
A common mistake that people make when trying to design something
completely foolproof is to underestimate the ingenuity of complete
fools. -- Douglas Adams
Luke Plant || http://lukeplant.me.uk/