How to cURL an Authenticated Django App?

Here is a fully coded answer. The idea of the solution is:

  1. you have to first visit the login page with GET to get the cookies file generated,
  2. then parse the CSRF token out of the cookies file
  3. and do the login using a POST request, passing the data with -d.

Afterwards you can perform any request always using that CSRF token in the data ($DJANGO_TOKEN) or with a custom X-CSRFToken header. To log out simply delete the cookies file.

Note that you need a referer (-e) to make Django’s CSRF checks happy.

LOGIN_URL=https://yourdjangowebsite.com/login/
YOUR_USER='username'
YOUR_PASS='password'
COOKIES=cookies.txt
CURL_BIN="curl -s -c $COOKIES -b $COOKIES -e $LOGIN_URL"

echo -n "Django Auth: get csrftoken ..."
$CURL_BIN $LOGIN_URL > /dev/null
DJANGO_TOKEN="csrfmiddlewaretoken=$(grep csrftoken $COOKIES | sed 's/^.*csrftoken\s*//')"

echo -n " perform login ..."
$CURL_BIN \
    -d "$DJANGO_TOKEN&username=$YOUR_USER&password=$YOUR_PASS" \
    -X POST $LOGIN_URL

echo -n " do something while logged in ..."
$CURL_BIN \
    -d "$DJANGO_TOKEN&..." \
    -X POST https://yourdjangowebsite.com/whatever/

echo " logout"
rm $COOKIES

I have a slightly more secure version of this code, which uses a file for submitting the POST data, as a Gist on GitHub: django-csrftoken-login-demo.bash

Interesting background reading on Django’s CSRF token is on docs.djangoproject.com.

Leave a Comment