How to throttle a Django view

In the last post, we built a todo list application with Django and Ember. It contained a register view to allow users to create accounts.

Right now, there is nothing to prevent an attacker from flooding that view and filling up the database with fake users. We want to throttle access to the view and limit the damage an attacker can cause.

I investigated several packages that provide throttling functionality, but the cleanest one I found is django-ratelimit. Here is how to use it:

Installing django-ratelimit and setting up the cache

First, we need to install it using pip:

Before we can use it to throttle views, we need to set up a cache for Django. Memcached is the recommended solution.

On Ubuntu 14.04, we can install Memcached and the python-memcached binding that Django needs with two commands:

Then we must add the CACHES dictionary to settings.py.

Check the Django documentation here for more detailed instructions.

Throttling a function-based view

Throttling the register view is as simple as applying a decorator to it.

We are setting the key argument to "ip", which means that we are throttling requests from the same IP address. It is possible to use different keys, but the IP address will work for our purposes.

We are also setting the rate to 10/h, or ten times per hour.

The method argument specifies which HTTP methods are to be throttled. ratelimit.UNSAFE is a shorthand for the list ['DELETE', 'PATCH', 'POST', 'PUT'].

If the limit is exceeded, the server will return 403 Forbidden.

Throttling a class-based view

If we had to throttle a class-based view, we would use the mixin that django-ratelimit provides.

The mixin works in much the same as the decorator, but instead of decorator arguments we are using class attributes prefixed with ratelimit_.

Specifying rates

We can specify rates in the format N/u or N/Mu, where N and M are integers and u is a unit. Here are some examples:

  • 1000/s – One thousand times per second
  • 5/m – Five times per minute
  • 10/h – Ten times per hour
  • 20/d – Twenty times per day
  • 100/5h – One hundred times every five hours

That’s it for now. django-ratelimit is a pretty good solution for throttling normal views. If you are using an API library such as Django Rest Framework, you should check if it has built-in throttling functionality.

Download Mastering Decorators

Mastering_decorators_cover

Enjoyed this article? Join the newsletter and get Mastering Decorators - a gentle 22-page introduction to one of the trickiest parts of Python.

Weekly-ish. No spam. Unsubscribe any time. Powered by ConvertKit