How to implement a custom authentication scheme in DRF?
To implement a custom authentication scheme, we need to subclass the DRF’s BaseAuthentication
class and override the .authenticate(self, request)
method.
The method should return a two-tuple of (user, auth)
if authentication succeeds, or None
otherwise. In some circumstances, we may raise an AuthenticationFailed
exception from the .authenticate()
method.
Example (from DRF docs):
Lets say we want to authenticate any incoming request as the user given by the username
in a custom request header named 'X_USERNAME'
.
Step-1: Create the Custom authentication class
To do that, we will create an authentication.py
file in my_app
.
# my_app/authentication.py
from django.contrib.auth.models import User
from rest_framework import authentication
from rest_framework import exceptions
class ExampleAuthentication(authentication.BaseAuthentication):
def authenticate(self, request):
username = request.META.get('X_USERNAME') # get the username request header
if not username: # no username passed in request headers
return None # authentication did not succeed
try:
user = User.objects.get(username=username) # get the user
except User.DoesNotExist:
raise exceptions.AuthenticationFailed('No such user') # raise exception if user does not exist
return (user, None) # authentication successful
Step-2: Specify the custom authentication class
After creating the custom authentication class, we need to define this authentication class in our DRF settings. Doing this, all the requests will be authenticated based on this authentication scheme.
'DEFAULT_AUTHENTICATION_CLASSES': (
'my_app.authentication.ExampleAuthentication', # custom authentication class
...
),
Note: If you want to use this custom authentication class on per-view basis or per-viewset basis and not on global level, you can define this authentication class explicitly in your views.
class MyView(APIView):
authentication_classes = (ExampleAuthentication,) # specify this authentication class in your view
...