Sling Academy
Home/Python/Python Requests module: How to send CSRF token in headers

Python Requests module: How to send CSRF token in headers

Last updated: January 02, 2024

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.

Next Article: Python ‘requests’ module: Handle XML response

Previous Article: requests vs aiohttp: Which is better for 2024?

Series: Python: Network & JSON tutorials

Python

You May Also Like

  • Python Warning: Secure coding is not enabled for restorable state
  • Python TypeError: write() argument must be str, not bytes
  • 4 ways to install Python modules on Windows without admin rights
  • Python TypeError: object of type ‘NoneType’ has no len()
  • Python: How to access command-line arguments (3 approaches)
  • Understanding ‘Never’ type in Python 3.11+ (5 examples)
  • Python: 3 Ways to Retrieve City/Country from IP Address
  • Using Type Aliases in Python: A Practical Guide (with Examples)
  • Python: Defining distinct types using NewType class
  • Using Optional Type in Python (explained with examples)
  • Python: How to Override Methods in Classes
  • Python: Define Generic Types for Lists of Nested Dictionaries
  • Python: Defining type for a list that can contain both numbers and strings
  • Using TypeGuard in Python (Python 3.10+)
  • Python: Using ‘NoReturn’ type with functions
  • Type Casting in Python: The Ultimate Guide (with Examples)
  • Python: Using type hints with class methods and properties
  • Python: Typing a function with default parameters
  • Python: Typing a function that can return multiple types