DRF Authentication & Permissions

In Django REST Framework, authentication identifies the user behind a request from its credentials, and permissions then decide whether that user is allowed to perform the requested action.

Learn DRF Authentication & Permissions in our free Django course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a…

Part of the free Django course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.

In this lesson you'll set authentication_classes (session, basic, and token), obtain and verify a token, control access with permission_classes like IsAuthenticated and IsAuthenticatedOrReadOnly , write a custom BasePermission , and add throttling to rate-limit clients.

A DRF view's authentication_classes list says how to identify the caller. SessionAuthentication uses the browser cookie, BasicAuthentication uses username and password, and TokenAuthentication reads an Authorization: Token <key> header and looks the key up to find the user.

Once the user is known, permission_classes decide if the request may proceed. IsAuthenticated blocks anonymous users entirely. IsAuthenticatedOrReadOnly lets anyone perform safe read methods (GET, HEAD, OPTIONS) but requires login for writes.

To obtain a token in the first place, wire up DRF's built-in view:

When the built-ins aren't enough, subclass BasePermission and implement has_object_permission — for example, to allow editing only by the object's owner. Separately, throttling caps how many requests a client may make, returning 429 Too Many Requests past the limit.

IsAuthenticated must let logged-in users through but deny anonymous ones. Fill in the blank so a None user is rejected.

The header is malformed — usually missing the Token scheme word before the key.

✅ Fix: send Authorization: Token <key> exactly, and add rest_framework.authtoken to INSTALLED_APPS , then migrate.

The user is authenticated but lacks permission — a different failure from being unauthenticated.

✅ Fix: check your permission_classes ; 401 means "log in", 403 means "logged in but not allowed".

You implemented has_permission but the check is per-object, so it should be has_object_permission .

✅ Fix: put object-level checks in has_object_permission(self, request, view, obj) .

Combine all three layers into one gate: authenticate the token, throttle the request, then apply an ownership permission — returning the right HTTP status for each outcome.

Lesson complete — your API is secured!

You can set authentication_classes , verify a token, obtain one from username and password, gate views with IsAuthenticated and IsAuthenticatedOrReadOnly , write a custom BasePermission , and throttle clients with a 429.

🚀 Up next: Deployment — ship your project safely with WSGI, static files, and production settings.

Practice quiz

What question does authentication answer in DRF?

  • Are you allowed to do this?
  • Who are you?
  • How fast are you going?
  • Which view handles this?

Answer: Who are you?. Authentication identifies the user behind a request from its credentials.

What question do permissions answer?

  • Are you allowed to do this?
  • Who are you?
  • What format is the body?
  • Which database to use?

Answer: Are you allowed to do this?. Permissions decide whether the identified user may perform the requested action.

What HTTP header format does TokenAuthentication expect?

  • Authorization: Bearer <key>
  • X-Api-Key: <key>
  • Authorization: Token <key>
  • Cookie: token=<key>

Answer: Authorization: Token <key>. TokenAuthentication reads the header 'Authorization: Token <key>'.

Which permission class allows reads for anyone but writes only for logged-in users?

  • IsAdminUser
  • AllowAny
  • IsAuthenticated
  • IsAuthenticatedOrReadOnly

Answer: IsAuthenticatedOrReadOnly. IsAuthenticatedOrReadOnly permits safe methods for all but requires auth for unsafe methods.

Which attribute on request is set by authentication before permissions run?

  • request.user
  • request.token
  • request.auth_id
  • request.session_key

Answer: request.user. Authentication runs first and sets request.user, which permission classes then check.

Which permission class requires a logged-in user for every request?

  • AllowAny
  • IsAuthenticated
  • IsAuthenticatedOrReadOnly
  • DjangoModelPermissions

Answer: IsAuthenticated. IsAuthenticated blocks anonymous users from all methods.

To write a custom object-level permission, which base class do you subclass?

  • models.Model
  • BaseSerializer
  • BasePermission
  • APIView

Answer: BasePermission. Subclass BasePermission and implement has_object_permission for object-level rules.

What status code does DRF return when a request exceeds the throttle limit?

  • 403 Forbidden
  • 401 Unauthorized
  • 400 Bad Request
  • 429 Too Many Requests

Answer: 429 Too Many Requests. Throttling returns 429 Too Many Requests once the rate limit is exceeded.

Which throttle classes limit anonymous vs authenticated users?

  • AnonRateThrottle and UserRateThrottle
  • LoginThrottle and LogoutThrottle
  • ReadThrottle and WriteThrottle
  • DayThrottle and HourThrottle

Answer: AnonRateThrottle and UserRateThrottle. DRF ships AnonRateThrottle and UserRateThrottle, configured with rates like 100/day and 1000/day.

How does a client typically obtain a token to use with TokenAuthentication?

  • By reading it from the admin page
  • By POSTing username and password to obtain_auth_token
  • By generating it client-side
  • By guessing the user id

Answer: By POSTing username and password to obtain_auth_token. DRF's obtain_auth_token view returns a token when you POST valid credentials.