REST framework includes a permission system to restrict access to views. Some of the built-in permissions of REST framework are:
- AllowAny: Unrestricted access, regardless of if a user is authenticated or not.
- IsAuthenticated: Allows access to authenticated users only.
- IsAuthenticatedOrReadOnly: Complete access to authenticated users. Anonymous users are only allowed to execute read methods such as GET, HEAD, or OPTIONS.
- DjangoModelPermissions: Permissions tied to django.contrib.auth. The view requires a queryset attribute. Only authenticated users with model permissions assigned are granted permission.
- DjangoObjectPermissions: Django permissions on a per-object basis.
If users are denied permission, they will usually get one of the following HTTP error codes:
- HTTP 401: Unauthorized
- HTTP 403: Permission denied
You can read more information about permissions at https://www.django-rest-framework.org/api-guide/permissions/.
Edit the api/views.py file of the courses application and add a permission_classes attribute to CourseEnrollView as follows:
from rest_framework.authentication import BasicAuthentication
from rest_framework.permissions import IsAuthenticated
class CourseEnrollView(APIView):
authentication_classes = (BasicAuthentication,)
permission_classes = (IsAuthenticated,)
# ...
We include the IsAuthenticated permission. This will prevent anonymous users from accessing the view. Now we can perform a POST request to our new API method.
Make sure the development server is running. Open the shell and run the following command:
curl -i -X POST http://127.0.0.1:8000/api/courses/1/enroll/
You will get the following response:
HTTP/1.1 401 Unauthorized
...
{"detail": "Authentication credentials were not provided."}
We get a 401 HTTP code as expected, since we are not authenticated. Let's use basic authentication with one of our users. Run the following command, replacing student:password with the credentials of an existing user:
curl -i -X POST -u student:password http://127.0.0.1:8000/api/courses/1/enroll/
You will get the following response:
HTTP/1.1 200 OK
...
{"enrolled": true}
You can access the administration site and check that the user is now enrolled in the course.