Authentication and authorization are key components of web security. In Django:
- Authentication verifies a user’s identity (e.g., login).
- Authorization determines what actions a user can perform.
Django provides built-in authentication and authorization tools, which can be extended using Django REST Framework (DRF) for API authentication.
1. Setting Up Authentication in Django
Django has a default authentication system for handling users, sessions, and permissions.
1.1 Enabling Authentication
Django’s authentication system is included in the default INSTALLED_APPS in settings.py
:
INSTALLED_APPS = [
'django.contrib.auth', # Handles authentication
'django.contrib.contenttypes',
]
Django provides a User
model for authentication. Run migrations if needed:
bashCopyEditpython manage.py migrate
2. User Authentication (Login & Logout)
Django provides built-in views for login and logout.
2.1 Creating a Superuser
To create an admin user:
python manage.py createsuperuser
Enter username, email, and password.
2.2 Logging in Users
In views.py:
from django.contrib.auth import authenticate, login, logout
from django.shortcuts import render, redirect
from django.contrib.auth.decorators import login_required
def user_login(request):
if request.method == "POST":
username = request.POST["username"]
password = request.POST["password"]
user = authenticate(request, username=username, password=password)
if user:
login(request, user)
return redirect("home")
return render(request, "login.html")
@login_required
def user_logout(request):
logout(request)
return redirect("login")
authenticate()
checks user credentials.login()
logs in the user.logout()
logs out the user.@login_required
ensures only logged-in users can access views.
Add URLs in urls.py:
from django.urls import path
from .views import user_login, user_logout
urlpatterns = [
path("login/", user_login, name="login"),
path("logout/", user_logout, name="logout"),
]
3. User Registration
3.1 Creating a Signup View
In views.py:
from django.contrib.auth.models import User
from django.contrib.auth import login
from django.shortcuts import render, redirect
def register(request):
if request.method == "POST":
username = request.POST["username"]
email = request.POST["email"]
password = request.POST["password"]
user = User.objects.create_user(username=username, email=email, password=password)
login(request, user)
return redirect("home")
return render(request, "register.html")
Add this to urls.py:
urlpatterns += [
path("register/", register, name="register"),
]
4. Authentication in Django REST Framework (DRF)
DRF provides built-in authentication classes.
4.1 Adding Authentication to DRF
In settings.py:
INSTALLED_APPS += ['rest_framework']
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.TokenAuthentication',
],
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated',
],
}
SessionAuthentication
enables Django’s session-based authentication.TokenAuthentication
allows token-based authentication.
Run migrations:
bashCopyEditpython manage.py migrate
5. Token-Based Authentication
To use token authentication:
pip install djangorestframework djangorestframework-simplejwt
Add 'rest_framework.authtoken'
to INSTALLED_APPS
:
pythonCopyEditINSTALLED_APPS += ['rest_framework.authtoken']
Run:
python manage.py migrate
5.1 Generating Tokens
Create an API view for authentication:
from rest_framework.authtoken.views import ObtainAuthToken
from rest_framework.authtoken.models import Token
from rest_framework.response import Response
class CustomAuthToken(ObtainAuthToken):
def post(self, request, *args, **kwargs):
serializer = self.serializer_class(data=request.data, context={'request': request})
serializer.is_valid(raise_exception=True)
user = serializer.validated_data['user']
token, created = Token.objects.get_or_create(user=user)
return Response({'token': token.key})
Add to urls.py:
from django.urls import path
from .views import CustomAuthToken
urlpatterns += [
path("api/token/", CustomAuthToken.as_view(), name="api-token"),
]
Now, users can authenticate by sending a POST
request to /api/token/
with their username and password.
6. JWT Authentication
To enable JWT authentication:
bashCopyEditpip install djangorestframework-simplejwt
In settings.py:
REST_FRAMEWORK['DEFAULT_AUTHENTICATION_CLASSES'].append(
'rest_framework_simplejwt.authentication.JWTAuthentication'
)
Add JWT token views to urls.py:
from rest_framework_simplejwt.views import TokenObtainPairView, TokenRefreshView
urlpatterns += [
path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
]
POST /api/token/
returns an access and refresh token.POST /api/token/refresh/
renews an expired access token.
7. Authorization in Django
7.1 Permissions in Django
Django provides groups and permissions for access control.
Assigning Permissions
from django.contrib.auth.models import Permission, User
user = User.objects.get(username="admin")
permission = Permission.objects.get(codename="add_user")
user.user_permissions.add(permission)
Checking Permissions in Views
from django.contrib.auth.decorators import permission_required
@permission_required("auth.add_user", raise_exception=True)
def my_view(request):
return render(request, "home.html")
- If the user lacks permission, an error is raised.
8. Permissions in Django REST Framework
DRF provides permission classes like:
AllowAny
: No authentication required.IsAuthenticated
: Only authenticated users can access.IsAdminUser
: Only admin users can access.IsAuthenticatedOrReadOnly
: Authenticated users can modify, others can only read.
8.1 Applying Permissions
Modify views.py:
from rest_framework.permissions import IsAuthenticated
from rest_framework.generics import ListCreateAPIView
from .models import User
from .serializers import UserSerializer
class UserListView(ListCreateAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
permission_classes = [IsAuthenticated] # Only authenticated users can access
Now, only authenticated users can access /api/users/
.
9. Role-Based Access Control (RBAC)
Django allows creating groups with permissions.
from django.contrib.auth.models import Group
admin_group = Group.objects.create(name="Admin")
user.groups.add(admin_group)
To restrict access based on groups:
from django.contrib.auth.decorators import user_passes_test
def is_admin(user):
return user.groups.filter(name="Admin").exists()
@user_passes_test(is_admin)
def admin_view(request):
return render(request, "admin.html")