Django: Fix CSRF Token Cookie not generating for non-html pages

This was a bit of a tricky one to debug. I was creating an API to log into the site via an app which communicated through JSON.

If the user was already logged in, the JSON response contained:

  • the account details
  • session ID (automatically set)
  • the CSRF token from request.META["CSRF_COOKIE"]

Otherwise, the user had to use HTTP POST to gain access to functionality. Since there wasn't any CSRF information yet, I decided to unprotect that view using @csrf_exempt.

This worked fine, as the JSON response was still giving back the right information:

  • account details
  • session ID
  • CSRF token from request.META["CSRF_COOKIE"]

The strange thing was that the CSRF token was being regenerated on each request, making any AJAX type calls fail the CSRF test every time even with "X-CSRFToken" set.

After a little investigation by delving into the Django source files, I realised there were 2 reasons why this was happening.

Firstly, the view to check/login was using @csrf_exempt. The cookie won't be set if the view is exempt. Removing the exemption case is fine, as the app will always perform an initial GET fetch request to check existing login data.

Strangely, this was still not enough to generate the "csrftoken" cookie.

A little more investigation by browsing made me realise something, it's generating when I view regular pages but not my special JSON view.

The view isn't terribly complicated either. Can you spot the problem causing the CSRF token to not be set?

c = {
'success': u.is_authenticated(),
'username': u.username if u.is_authenticated() else '',
'csrf_token': request.META["CSRF_COOKIE"],
}

return HttpResponse(JSONEncoder().encode(c))

No? Don't worry, I didn't either.

The cookie won't be set unless the content/mime type of the page is a known HTML type (such as "text/html" or "application/xhtml+xml").

So apart from changing the mime-type, what can we do?

Easy. Just add in this line just before returning HttpResponse.

# This triggers CsrfViewMiddleware to make it set the CSRF token upon first request.
request.META["CSRF_COOKIE_USED"] = True

That's all it needed. That sneaky little bastard wasn't in the docs when I looked at it, but it should solve this fairly niche issue.

81366568
Now, off to solve more important problems!

django: taggit error "FieldError: Cannot resolve keyword 'tagged_items' into field."

Even with an extremely basic model, the django-taggit submodule was not working. I'm not even sure if this was tested before merging.

class TwigTest(models.Model):
taggit = TaggableManager()

TwigTest.objects.filter(taggit__name = 'dell')

FieldError: Cannot resolve keyword 'tagged_items' into field. Choices are: id, taggit, twigtest_tagged_items

Took a look around a few links gave no certain solutions, so I managed to fix it by commenting out TaggableManager.extra_filters() in manage.py.

Take it with a grain of salt, because I have no idea what I may have broken by doing this.

229196-254280708008944-785296244-n
These instructions will work too!

Sources

Android & Eclipse: Fixing "Derived File Encountered - This file is derived. Do you really want to edit it?"

image

This annoying little quirk also caused my file to stop showing up in the "open resource" dialog.

It happened when I accidentally dragged the java file into the "gen" folder. I guess the SDK automatically marks anything in there as derived.

Derived just tells the Eclipse IDE that files were generated by the system, and will be overwritten if something else changed.

To remove it, simply right click on the file and select "Properties".

From there, untick "Derived" and then save it.

Now, back to business!

bSGfJ

Django: Get name of SQL table from Model

It's rare, but sometimes you have to delve deep into the deep edges of Django's ORM to do raw SQL.

Something that would definitely make your life easier is knowing how to get the table name from a models.Model object.

You can fetch it by grabbing YourModel._meta.db_table.

ibvZA3Ux1aA3Nu
Grab that Model, Gangnam style!

 
Copyright © Twig's Tech Tips
Theme by BloggerThemes & TopWPThemes Sponsored by iBlogtoBlog