Prevent unauthorised users from accessing views and provide feedback using the @decorator method, such as for RECAPTCHA protected form submissions
In this article, I will try to outline how you can write your own custom decorators in Django using its user_passes_test
function. Decorators are a way to restrict access to views based on the request method or control caching behaviour. This is particularly useful when you want to separate logged-in users from unauthenticated users or create an admin page that only privileged users can access.
Django has several built-in decorators, but their main issue is that they do not provide user feedback. Django also has a built-in messages framework that uses the SESSION_COOKIE
to store messages and display them after submitting or reloading webpages as a means of user feedback. We’re going to incorporate this in our custom decorators. We’re also going to use Google’s RECAPTCHA
to protect our form submissions from spam and abuse and include this in a decorator.
In full, what we’ll do in this article is:
- Adjust Django’s
user_passes_test
so that it provides user feedback using Django’s messages framework - Write three custom decorators:
@superuser_required
,@staff_required
and@unauthenticated_required
- Use Google’s
RECAPTCHA
to provide a@check_recaptcha
decorator for protecting form submissions from abuse
Decorators are an easy way to clean up your code and separate the view authentication process from the view functionality. Django has several useful built-in decorators such as @login_required
, @permission_required
for user permissions and @require_http_methods
for restricting request methods (GET|POST
).
When you want to perform some sort of custom view authentication, you can do that in the view itself, as shown below. However, when you apply this authentication to several routes, it becomes verbose to copy-paste this example in every route. That’s when I started writing custom decorators since only one line @custom_decorator(args*)
was needed to authenticate and protect views.