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.