8.1 Authentication
Authentication is the mechanism of identifying/verifies a user during an incoming request.
Authentication gives us some advanced behavior
like:
* Restriction on create, update or delete
* Unauthenticated requests should have read-only access.
* Adding throttling policies
8.1.1 Authentication vs Authorization
Authentication verifies a user is who they claim to be
. or whether it anonymous or system user
.
Authorization determines what an authenticated user is allowed to do/access
.
First check Authentication/identification
and then if the user is authenticated give some Permission/Authorization
8.1.2 How authentication is determined
FAQ: How is authentication handled in Django REST framework?
https://www.django-rest-framework.org/api-guide/authentication/#how-authentication-is-determined
The authentication schemes are always defined as a list of classes.
REST framework will attempt to authenticate with each class in the list, and will set request.user
and request.auth
using the return value of the first class that successfully authenticates.
If no class authenticates, request.user
will be set to an instance of django.contrib.auth.models.AnonymousUser, and request.auth
will be set to None.
The value of request.user
and request.auth
for unauthenticated requests can be modified using the UNAUTHENTICATED_USER and UNAUTHENTICATED_TOKEN settings.
8.1.3 Setting the authentication scheme
The default authentication schemes may be set globally
, using the DEFAULT_AUTHENTICATION_CLASSES setting. For example.
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.BasicAuthentication',
'rest_framework.authentication.SessionAuthentication',
]
}
You can also set the authentication scheme on a per-view
# For - class based views
class ExampleView(APIView):
authentication_classes = [SessionAuthentication, BasicAuthentication]
pass
# For - function based view
@api_view(['GET'])
@authentication_classes([SessionAuthentication, BasicAuthentication])
def example_view(request, format=None):
pass
8.2 Types of Authentication
- TokenAuthentication
- SessionAuthentication,
- BasicAuthentication
8.2.1 BasicAuthentication
This authentication scheme uses HTTP Basic Authentication, signed against a user’s username and password
.
Basic authentication is generally only appropriate for testing.
If successfully authenticated, BasicAuthentication provides the following credentials.
request.user
will be a Django User instance.request.auth
will be None.
Note: If you use BasicAuthentication in production you must ensure that your API is only available over https.
You should also ensure that your API clients will always re-request the username and password
at login, and will never store
those details to persistent storage.
Enable BasicAuthentication
- by adding below two classed in views
authentication_classes = (BasicAuthentication,)
permission_classes = [permissions.IsAuthenticatedOrReadOnly]
View CODE here: https://github.com/amrit94/drf-test/tree/09-BasicAuth
Code Difference: https://github.com/amrit94/drf-test/commit/98abb04e23f1a44befc67a28a04a2cd8dc52d067
Make API request using Postman
- For every request pass username & password in
Auth > Basic Auth
- PATH: /users/
IsAuthenticated
- Only Authenticated can make a request
- PATH: /users/1/
IsAuthenticatedOrReadOnly
- Anyone can read, Only Authenticated can update
8.2.2 SessionAuthentication
- Work only for Browsable API login i.e
works only on Borwser
- The server will
create a session
for the user after the user logs in. - The session id is then
stored on a cookie
on the user’s browser.
Session authentication is appropriate for AJAX clients
that are running in the same session context as your website.
- csrf_token is used
Enable SessionAuthentication
- by adding below two classed in views
# urls.py
path('api-auth/', include('rest_framework.urls'))
View CODE here: https://github.com/amrit94/drf-test/tree/10-SessionAuth
Code Difference: https://github.com/amrit94/drf-test/commit/18802916bf2ee8959874dc509e34335631e60165
Make API request using Browser - Incognito mode
- Login PATH: /api-auth/login/
- Use username and password to login
- Logout PATH: /api-auth/logout/
- Clear session
- PATH: /albums/ and /albums/1/
- Only Authenticated can update
Article:
- https://www.youtube.com/watch?v=HYOvEIimVzI
- https://www.django-rest-framework.org/api-guide/authentication/#sessionauthentication
8.2.3 TokenAuthentication
The token authentication works by exchanging username and password for a token
that will be used
in all subsequent requests so to identify the user on the server side.
Token authentication is suitable for client-server applications
, where the token is safely stored.
You should never expose your token, as it would be (sort of) equivalent of a handing out your username and password.
There are various 3rd party packages
for Token authentication
8.3 Permissions
Authentication or identification by itself is not usually sufficient to gain access to information or code.
For that, the entity requesting access must have authorization
Permissions are used to grant or deny access
for different classes of users to different parts of the API.
If permission_class is used then and the request must pass all permission classes
Setting the permission policy
The default permission policy may be set globally
, using the DEFAULT_PERMISSION_CLASSES setting. For example.
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticatedOrReadOnly',
]
}
If not specified, i.e. permission policy not set globally
then this allows unrestricted access
# No need to set explictly
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.AllowAny',
]
You can also set the permission policy on a per-view
# For - class based views
class ExampleView(APIView):
permission_classes = [IsAuthenticated|ReadOnly]
pass
# For - function based view
@api_view(['GET'])
@permission_classes([IsAuthenticated])
def example_view(request, format=None)
pass