DEV Community

Cover image for My Journey as a Backend Developer: Solving Complex Authentication and Authorization Challenge
kihuni
kihuni

Posted on

My Journey as a Backend Developer: Solving Complex Authentication and Authorization Challenge

Being a backend developer often means solving complex problems that require a deep understanding of the underlying systems and technologies. Recently, I faced a challenging issue related to authentication and authorization in a Django project. Here’s a detailed breakdown of how I tackled this problem and why I’m excited about the journey I’m about to start with the HNG Internship.

The Problem: Custom Authentication and Authorization

In a recent project, I was tasked with implementing a custom authentication system that required users to log in using their email addresses instead of usernames. Additionally, the project had specific authorization requirements, such as role-based access control (RBAC) to manage user permissions efficiently.

Step-by-Step Solution

  • Step 1: Custom User Model

The first step was to create a custom user model that used email as the unique identifier. This involved subclassing Django’s AbstractBaseUser and BaseUserManager.

from django.contrib.auth.models import AbstractBaseUser, BaseUserManager

class MyUserManager(BaseUserManager):
    def create_user(self, email, password=None):
        if not email:
            raise ValueError("Users must have an email address")
        user = self.model(email=self.normalize_email(email))
        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_superuser(self, email, password=None):
        user = self.create_user(email, password)
        user.is_admin = True
        user.save(using=self._db)
        return user

class MyUser(AbstractBaseUser):
    email = models.EmailField(unique=True)
    is_active = models.BooleanField(default=True)
    is_admin = models.BooleanField(default=False)

    objects = MyUserManager()

    USERNAME_FIELD = 'email'

Enter fullscreen mode Exit fullscreen mode
  • Step 2: Update Settings

Next, I updated the settings to use the custom user model.

AUTH_USER_MODEL = 'myapp.MyUser'
Enter fullscreen mode Exit fullscreen mode
  • Step 3: Custom Authentication Backend

To support authentication via email, I created a custom authentication backend.

from django.contrib.auth.backends import BaseBackend
from django.contrib.auth import get_user_model

class EmailBackend(BaseBackend):
    def authenticate(self, request, email=None, password=None):
        User = get_user_model()
        try:
            user = User.objects.get(email=email)
            if user.check_password(password):
                return user
        except User.DoesNotExist:
            return None

    def get_user(self, user_id):
        User = get_user_model()
        try:
            return User.objects.get(pk=user_id)
        except User.DoesNotExist:
            return None

Enter fullscreen mode Exit fullscreen mode
  • Step 4: Update Authentication Backends

I updated the AUTHENTICATION_BACKENDS setting to include the custom backend.

AUTHENTICATION_BACKENDS = [
    'myapp.backends.EmailBackend',
    'django.contrib.auth.backends.ModelBackend',
]

Enter fullscreen mode Exit fullscreen mode
  • Step 5: Implement Role-Based Access Control (RBAC)

For RBAC, I used Django’s built-in groups and permissions. I defined custom permissions in the Meta class of relevant models and assigned these permissions to user groups.

class MyModel(models.Model):
    ...
    class Meta:
        permissions = [
            ("can_view", "Can view"),
            ("can_edit", "Can edit"),
        ]

Enter fullscreen mode Exit fullscreen mode

Assigning permissions to groups:

from django.contrib.auth.models import Group, Permission

view_permission = Permission.objects.get(codename='can_view')
edit_permission = Permission.objects.get(codename='can_edit')

viewer_group = Group.objects.create(name='Viewers')
viewer_group.permissions.add(view_permission)

editor_group = Group.objects.create(name='Editors')
editor_group.permissions.add(view_permission, edit_permission)

Enter fullscreen mode Exit fullscreen mode

Checking permissions in views:

from django.contrib.auth.decorators import permission_required

@permission_required('myapp.can_view')
def my_view(request):
    ...

Enter fullscreen mode Exit fullscreen mode

Personal Journey and HNG Internship

My journey as a backend developer has been marked by continuous learning and problem-solving. Each challenge, like the one described above, has honed my skills and deepened my understanding of web development.

I am about to embark on an exciting journey with the HNG Internship. This opportunity is about enhancing my technical skills and networking with like-minded professionals and mentors who can guide me toward excellence. The internship offers a platform to work on real-world projects, which is invaluable for practical learning.

Why HNG Internship?

  • Hands-on Experience: The internship will allow me to work on diverse projects, sharpening my problem-solving skills.

  • Mentorship: Access to experienced mentors will provide guidance and insights that are crucial for professional growth.

  • Networking: Connecting with peers and industry professionals will expand my professional network, opening up future opportunities.

Conclusion

Solving complex problems is a significant part of being a backend developer. The challenge of implementing custom authentication and authorization in Django not only tested my skills but also reaffirmed my passion for backend development. As I step into the HNG Internship, I am eager to learn, grow, and contribute to impactful projects. This journey is a stepping stone towards a future where I can leverage my skills to build secure and efficient applications.

Image of Timescale

🚀 pgai Vectorizer: SQLAlchemy and LiteLLM Make Vector Search Simple

We built pgai Vectorizer to simplify embedding management for AI applications—without needing a separate database or complex infrastructure. Since launch, developers have created over 3,000 vectorizers on Timescale Cloud, with many more self-hosted.

Read full post →

Top comments (0)

Postmark Image

Speedy emails, satisfied customers

Are delayed transactional emails costing you user satisfaction? Postmark delivers your emails almost instantly, keeping your customers happy and connected.

Sign up