Python Requests module: How to send CSRF token in headers

Updated: January 2, 2024 By: Guest Contributor Post a comment

Introduction

The Python Requests module enables HTTP communication in a simple and straightforward manner. When dealing with web forms and POST requests, it’s often necessary to handle CSRF tokens for security. This tutorial walks through sending CSRF tokens using the Requests module.

What is a CSRF Token?

Before diving into the code, let’s understand what a CSRF (Cross-Site Request Forgery) token is. It is a unique, secret, and unpredictable value that a server generates to prevent CSRF attacks. It is included in requests sent from the client to the server to ensure that the request comes from a legitimate source.

Obtaining the CSRF Token

First, you’ll need to obtain the CSRF token that you’ll send in the header of subsequent requests. This can usually be done by sending a GET request to the page that contains the form you want to submit.

import requests

# Send a GET request to the form page
response = requests.get('https://example.com/form')

# Extract the CSRF token
csrf_token = response.cookies['csrftoken']

Sending the CSRF Token in Headers

Once you have the CSRF token, you can include it in the headers of a POST request.

# Define the data you want to send
payload = {
  'username': 'someuser',
  'password': 'safepassword'
}

# Include the CSRF token in the header
headers = {'X-CSRFToken': csrf_token}

# Send a POST request with the CSRF token
response = requests.post('https://example.com/form', data=payload, headers=headers)

# Check the response
if response.status_code == 200:
  print('Form submitted successfully!')
else:
  print('Failed to submit the form.')

Advanced Usage: Session Objects

To handle CSRF tokens in a more sophisticated manner, you can use Session objects in Requests, which keep track of certain parameters across requests.

session = requests.Session()

# Perform a GET request to obtain the CSRF token
response = session.get('https://example.com/form')
csrf_token = session.cookies.get('csrftoken', None)

# Update session headers with the CSRF token
session.headers.update({'X-CSRFToken': csrf_token})

# Now use the session to post data
response = session.post('https://example.com/form', data=payload)

# Check the response
if response.status_code == 200:
  print('Form submitted successfully with session object!')
else:
  print('Failed to submit the form using session.')

Handling CSRF Token in AJAX Requests

When working with AJAX Requests, you must also properly manage the CSRF token. Here’s how to do it with the Python Requests library and a front-end AJAX call.

# Assume the CSRF token has been acquired and AJAX request is being handled by something like JavaScript/jQuery.

// JavaScript (e.g., jQuery AJAX)
$.ajax({
  url: 'https://example.com/submit-form',
  type: 'post',
  data: payload,
  headers: {
    'X-CSRFToken': csrf_token
  },
  success: function(data) {
    console.log('AJAX form submitted successfully!');
  },
  error: function() {
    console.log('Failed to submit AJAX form.');
  }
});

Error Handling and Best Practices

Ensure your code is robust by handling potential errors such as missing or invalid CSRF tokens, failed connections, and unexpected response codes.

# Simple error handling example in Python
try:
  response = requests.post('https://example.com/form', data=payload, headers=headers)
  response.raise_for_status()
except requests.exceptions.HTTPError as http_err:
  print(f'HTTP error occurred: {http_err}')
except Exception as err:
  print(f'An error occurred: {err}')

# Validate the CSRF token is present
if 'csrftoken' not in response.cookies:
  print('CSRF token not found.')
else:
  csrf_token = response.cookies['csrftoken']

Conclusion

This tutorial provided a comprehensive guide on how to handle CSRF tokens in the Python Requests module. Correctly utilizing CSRF tokens is critical for web security, and with this knowledge, you can secure your Python applications against CSRF attacks. Experiment with advanced techniques and error handling to create more sophisticated and robust applications.