1

I want to create an App for Customers where every customer has its own DB. So as Login information they need to enter three different fields: customernumber, username, password.

The username and password should do the normal authentication stuff and the customernumber is there to go to the right database user table for authentication i can go to other databases through the using() function.

class CustomAuthBackend(ModelBackend):

def authenticate(self, request, username=None, password=None, **kwargs):
    user = CustomUser.objects.using(request.POST['kundennr']).get(username=username)
    if user.check_password(password) and self.user_can_authenticate(user) :
         try:
            user = CustomUser.objects.using(request.POST['kundennr']).get(username=username)
            return user
         except User.DoesNotExist:
            return None

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

The authentication function works fine that way the problem i have is the get_user function i guess because the get_user function has no request where i can define which database it should call on. because everytime i call {% if user.is_authenticated %} it goes to the default database and says user is Anonymous. I dont know the right way to solve this problem is my solution just wrong?

2
  • What you want is fairly complicated and your solution won't work. Look at this post or google for "django multi-tenant" Commented Nov 21, 2018 at 12:50
  • Or look at this book Commented Nov 21, 2018 at 12:56

1 Answer 1

1

okay after trying some stuff i got a solution which i think works for the first step but i dont know if there are security problems or any other errors if i use it like this

from app.models import CustomUser
from django.contrib.auth.backends import ModelBackend
from django.contrib.auth import login as auth_login
from app.middleware import ThreadLocal

class CustomAuthBackend(ModelBackend):

def authenticate(self, request, username=None, password=None, **kwargs):
    user = CustomUser.objects.using(request.POST['kundennr']).get(username=username)
    if user.check_password(password) and self.user_can_authenticate(user) :
         try:
            user = CustomUser.objects.using(request.POST['kundennr']).get(username=username)
            request.session['kundennr']=request.POST['kundennr']
            return user
         except User.DoesNotExist:
            return None

def get_user(self, user_id):
    try:
        request = ThreadLocal.get_current_request()
        return CustomUser.objects.using(request.session['kundennr']).get(pk=user_id)
    except User.DoesNotExist:
        return None

i imported a ThreadLocal.py into middleware so i can get the request object in get_user and when i login i save the customer into a session variable which i call in get_user then is this solution acceptable or are there some risks?

Sign up to request clarification or add additional context in comments.

6 Comments

The problem with this approach is that for every object you want to fetch (not just User) you have to add the using() with the correct database. This becomes quite unmanageable. Also note that you're fetching the user in the first line of authenticate (without try .. except) and then fetching the same user again.
How are you going to create the new databases each time you get a new customer and register the database with Django (so that you can actually do using())?
i use mssql and got a script to create new database for a customer so i need to edit the settings.py for every new customer i guess and ye i have to use using() all the time but for me its not about if its a solution thats not beautiful i just want to know if it works this way or are there any risks in errors or security. ye i need to make a try block the first time i fetch the user in authenticate but when i have a session variable who saves the customernumber i just can copy using(request.session['kundennr']) every time i got a database access right?
What session backend are you using? Cookies or database?
Then I guess in terms of security I don't see how a user could manipulate the session data, so this seems safe to me, as long as you: only allow requests over https (for your entire site) and make sure you have SESSION_COOKIE_SECURE set to True in your settings.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.