Mohan
Mohan

Reputation: 4829

Django Multiple Auth Models

I am working on a project where I need to have 3 types of Users.

I want to be having seperate Models for all three of them Vendor & Customers instead of having a type field in a common User Model.

My first approach to this problem was to define all models by sub-classing the AbstractUser model

# models.py
from django.contrib.auth.models import AbstractUser

class Customer(AbstractUser):
    pass


class Vendor(AbstractUser):
    pass

And add a custom Authentication backend to handle the authentication of users based on the request object.

# settings.py

AUTHENTICATION_BACKENDS = ['backends.CustomAuthBackend']

And my backends.py file will contain the logic to authenticate users and use different models for each one based on the request object.

# backends.py
from __future__ import print_function


class CustomAuthBackend(object):

    def authenticate(self, request, username=None, password=None):
       # authenticate user based on request object

    def get_user(self, user_id):
        # logic to get user

However this does not work and looks like i also need to specifiy the AUTH_USER_MODEL in settings.py which is used for authentication.

Is it possible at all.Does Django allow to authenticate from 3 different tables. How can I go ahead with this ? Is there any other approach to this and what should I change ?

Upvotes: 5

Views: 6705

Answers (2)

zhiqiang huang
zhiqiang huang

Reputation: 371

I have done similar staff a couple days ago, you are in the right approach. But there are a few other things needed to change to make it work. I'll explain what I did to make it success.

First, you have to custom your own user model, and you have to do it in the first place before you make the migrations. And also in the model file define different userManagers to manager different type of users. Then in your settings file you have to set AUTH_USER_MODEL and AUTHENTICATION_BACKENDS, AUTH_USER_MODEL is the default user model django will use for authentication and you can only set to one user model, but for AUTHENTICATION_BACKENDS you can have multiple backends,it's a list and django will loop every option inside to authenticate. by default it use django.contrib.auth.backends.ModelBackend, you can add your own auth backends. Check this on how to make your own authentication backend:https://docs.djangoproject.com/en/1.11/topics/auth/customizing/#writing-an-authentication-backend. And depends on your application, you may also need to custom the serializer function and override some classes to make it work. In my own application, I was using DRF and JWT token to authenticate, so I also override some of the function which by default use the AUTH_USER_MODEL variable. In the end, I'm able to use admin model to login the admin page and use another custom user model to authenticate the application and get the JWT token. Anyway, always reference this page: https://docs.djangoproject.com/en/1.11/topics/auth/customizing/#customizing-authentication-in-django. Hope this can help you in your application.

Upvotes: 3

dahrens
dahrens

Reputation: 3959

django.contrib.auth is designed to work with one UserModel. Depending on what you want to achieve there are different apporaches.

If you just want to store different kind of profile/meta data for the different types of user you might use multi table inheritance - in this case you might stick with the default user model.

When it comes to different permissions based on the user type you should not solve this using separate classes. Instead use groups. This approach is much more flexible. It can nearly always happen that one person should belong to more than one group of users. When you model this based on the user classes you are in trouble.

Upvotes: 1

Related Questions