42

within my django app I am storing strings of html in the db that will then be displayed on the users' home pages as "messages". Some of these messages contain forms, but not being written in the template language, I am not able to insert the csrf token (thus breaking the app).

Is there a way to insert this token directly from within the python files i'm editing? i'm looking for something along the lines of:

csrf_token = django.csrf.generate()
message = "press the button please: <form><input type='hidden' name='csrf_token' value='%s'><input type='submit' value='press here'></form>" % (csrf_token)

any other solution that would work in a similar scenario would be great. Thanks

Edit: Actually that's not going to work because the token is different for each session, so storing it in the db is not very useful. is there a way to dynamically load the token within the view?

ergelo
  • 923
  • 2
  • 9
  • 15
  • What do you mean by 'dynamically load the token within the view'? – Reto Aebersold Jul 20 '10 at 15:25
  • the form is stored as a string in the database, so if i store the token there it will be invalid as soon as it is loaded in a new session. If it were possible to load a new token from inside the view, then I could intercept the html as it was being rendered, insert the appropriate token, and display the working form. The key thing here is that I'm not going through a template to insert the token. Does that make it clearer? – ergelo Jul 21 '10 at 12:41
  • can't you just use the csrf_protect decorator? – sureshvv Nov 24 '16 at 18:30

3 Answers3

55

Call django.middleware.csrf.get_token(request) to get the CSRF token.

Nicu Surdu
  • 8,172
  • 9
  • 68
  • 108
viam0Zah
  • 25,949
  • 8
  • 77
  • 100
48

The way to use it, is to use it directly in the templates.

From the documentation,:

<form action="" method="post">
{% csrf_token %}

is all you have to include.

lprsd
  • 84,407
  • 47
  • 135
  • 168
  • thanks. the problem is that the 'message' is created in a view, and stored into the db without ever going through a view. I'll solve the problem by turning the form button into a link and going through a view to bypass the csrf. – ergelo Jul 20 '10 at 17:28
  • 12
    the question is for the case where you dont use django's templates – Jenia Ivanov May 19 '14 at 16:45
  • This solved it for me during the installation of Django-CMS! For some reason it would not login without this token in the only template I had. Weird. – MadPhysicist May 04 '17 at 21:16
11

The accepted answer assumes that token is already set in the request object.

Maybe something like this is better:

from django.middleware import csrf
def get_or_create_csrf_token(request):
    token = request.META.get('CSRF_COOKIE', None)
    if token is None:
        token = csrf._get_new_csrf_key()
        request.META['CSRF_COOKIE'] = token
    request.META['CSRF_COOKIE_USED'] = True
    return token
Evgeny
  • 10,698
  • 9
  • 60
  • 70