2014-12-13 2 views
2

Я хочу создать панель управления, которую могут использовать как простые пользователи, так и администраторы. У меня две базы данных. В admin_db я храню администраторов, а в mysql_db у меня есть простые пользователи. Пользователь, который является администратором, имеет одно и то же имя пользователя в admin_db и в mysql_db, но, вероятно, другой проход (для безопасности и другие причины).Множественная аутентификация в разных базах данных

Моя концепция следующие: журналы

пользователя в Если имя пользователя существует в admin_db, дают возможность для входа в систему в качестве администратора тоже (возможно добавить еще одну кнопку в HTML).. В противном случае отображаются только простые пользовательские параметры.

Как я могу это достичь? В настоящее время я использую по умолчанию @login_required но он проверяет лишь один децибел, я не могу переключаться между базами данных .. Как я могу сделать что-то вроде следующего:

def login(db=default, username=None): 
    #check the authentication 

...... 

logged_in = False 
while not logged_in: 
    if logged_in_mysql: 
     if username in admin_db: 
      show button 'login_as_admin' 
     else: 
      continue as normal 
    else: 
     login(mysql_db) 

..... 

if user_clicks_login_as_admin: 
    login(admin_db, god) 

ответ

2

Поскольку никто не ответил, я нашел решение на мой владеть, и разместить его здесь для тех, кто с той же проблемой:

Прежде всего я имел 2 базы данных в моем settings.py:

settings.py 

DATABASES = { 
    'default': { 
     'NAME': 'myadmin', 
     'ENGINE': 'django.db.backends.mysql', 
     'USER': 'root', 
     'PASSWORD': 'abc123', 
     'HOST': '127.0.0.1', 
     'PORT': '3306', 
    }, 
    'mysql': { 
     'NAME': 'mydb', 
     'ENGINE': 'django.db.backends.mysql', 
     'USER': 'root', 
     'PASSWORD': 'abc123', 
     'HOST': '127.0.0.1', 
     'PORT': '3306', 
    } 
} 

концепция в том, что пользователь в одной БД может быть также в админам db (или наоборот). Чтобы помочь django играть с обоими базами данных, в то же время мне пришлось создать маршрутизатор, который будет указывать django на правый db для моего приложения для входа. Я создал routers.py в моем проекте корневой папке:

routers.py 

class LoginRouter(object): 
    """ 
     Router for routing login operations to mysql db 
    """ 
    def db_for_read(self, model, **hints): 
     """ 
      Point all operations on login models to mysql 
     """ 
     if model._meta.app_label == 'login': 
      return 'mysql' 
     return 'default' 

    def db_for_write(self, model, **hints): 
     """ 
      Point all operations on login models to 'mysql' 
     """ 
     if model._meta.app_label == 'login': 
      return 'mysql' 
     return 'default' 

    def allow_relation(self, obj1, obj2, **hints): 
     """ 
      Allow any relation if a both models in login app 
     """ 
     if obj1._meta.app_label == 'login' and obj2._meta.app_label == 'login': 
      return True 
     # Allow if neither is login app 
     elif 'mysql' not in [obj1._meta.app_label, obj2._meta.app_label]: 
      return True 
     return False 

    def allow_syncdb(self, db, model): 
     if db == 'mysql' or model._meta.app_label == "login": 
      return False # we're not using syncdb on our legacy database 
     else: # but all other models/databases are fine 
      return True 

Я также должен добавить следующую строку в мой settings.py

DATABASE_ROUTERS = ['routers.LoginRouter']

Теперь, если у вас есть другой тип аутентификации, чем классические Джанго аутентификация пользователя , вам нужно создать сервер аутентификации. Я должен был сделать это, потому что в моем другом db было поле под названием name, которое было «именем пользователя» для аутентификации. Обратите внимание на то, что в моей модели я много таблиц, поэтому я звоню dovecot.Users (мне нужна таблица Users здесь) Так снова в моей корневой папке я создал backends.py и я добавил следующее:

backends.py 

#my custom model from my outer db 
from login import models as dovecot 
class EmailAuthBackend(object): 
    """ 
    Email Authentication Backend 

    Allows a user to sign in using an email/password pair rather than 
    a username/password pair. 
    """ 
    def authenticate(self, username=None, password=None): 
     """ Authenticate a user based on email address as the user name. """ 
     try: 
      user = dovecot.Users.objects.get(name=username) 
      if self.check_password(password, user): 
       return user 
     except dovecot.Users.DoesNotExist: 
      return None 

    def get_user(self, user_id): 
     """ Get a User object from the user_id. """ 
     try: 
      return dovecot.Users.objects.get(pk=user_id) 
     except dovecot.Users.DoesNotExist: 
      return None 

затем я добавил к моему settings.py следующее (помните, приоритетные вопросы, когда Джанго succeds в интерфейсе, он не будет продолжать в дальнейшем я упомяну позже, как я проверил в обоих д.б.н.!.):

settings.py 

AUTHENTICATION_BACKENDS = ('backends.EmailAuthBackend', 'django.contrib.auth.backends.ModelBackend') 

Так что теперь я создал приложение, в котором django может проверить оба db, чтобы узнать, существует ли пользователь и аутентифицировать их. Но я также хотел посмотреть, был ли пользователь в mail_db также права администратора .. Так что в моем views.py в моем приложении для входа я создал login_user:

from login.models import Users as dov 
from django.shortcuts import render_to_response, RequestContext 
from django.contrib.auth import authenticate, login 
from django.contrib.auth.models import User 
from django.db import models 
from django.contrib.auth.decorators import login_required 


def login_user(request): 
    state = "Please log in below..." 
    username, password = '', '' 
    if request.POST: 
     username = request.POST.get('username') 
     password = request.POST.get('password') 

     user = authenticate(username=username, password=password) 
     if user is not None: 
      if user.is_active: 
       login(request, user) 
       state = "You're successfully logged in!" 
      else: 
       state = "Your account is not active, please contact the site admin." 
     else: 
      state = "Your username and/or password were incorrect." 

     if username != '' and 'incorrect' not in state: 
      db = [] 
      #check to see in how many dbs' is the specific user 
      try: 
       dov.objects.using('mysql').get(name=username) 
       db.append('mysql') 
      except models.ObjectDoesNotExist: 
       #we are expecting such exception if user is not in db 
       pass 
      except: 
       #todo return error page 
       return render_to_response('auth.html', {'state': 'ERROR', 'username': username}, 
              context_instance=RequestContext(request)) 
      try: 
       User.objects.using('default').get(username=username) 
       db.append('admin') 
       pass 
      except models.ObjectDoesNotExist: 
       #we are expecting such exception if user is not in db 
       pass 
      except: 
       #todo return error page 
       return render_to_response('auth.html', {'state': 'ERROR', 'username': username}, 
              context_instance=RequestContext(request)) 
      return render_to_response('home.html', {'db': '{}'.format(','.join(db)), 'user': user}, context_instance=RequestContext(request)) 
    return render_to_response('auth.html',{'state':state, 'username': username}, context_instance=RequestContext(request)) 

Итак, теперь вы войти в систему пользователя, и вы также проверить, если пользователь существует в обоих DBS. Если пользователь существует в обоих случаях, вы можете предложить администратору логин :)

Надеюсь, что это поможет любому, у кого есть подобные проблемы. Я искал какое-то время в Интернете и не смог найти полное решение, поэтому я решил поставить это здесь для будущей ссылки. Я надеюсь, что ничего не забыл или допустил ошибки