2013-06-12 3 views
9

Brauchen Sie ernsthafte Hilfe hier.Django Multiple Authentication Backend für ein Projekt, WIE?

Ich habe eine Anwendung in django/Python geschrieben und ich habe es zu erweitern und umfassen eine andere Lösung als „App“ in dieser Anwendung. Zum Beispiel meines app „my_new_app“ Jetzt heißt integriert werden gibt es eine Back-End-Authentifizierung für die Hauptanwendung geschrieben und ich es nicht verwenden kann. Ich habe eine MySQL-Datenbank abfragen und die Haupt-App verwendet Cassendra und meist wieder. Also meine Frage ist, gibt es eine Möglichkeit, dass ich ein separates Authentifizierungs-Backend für die neue App "my_new_app" verwenden und die beiden in der gleichen Domäne ausführen kann? Frage ist vielleicht nicht so klar, ich werde klären, wenn gefragt.

Antwort

24

Sie können haben mehrere Authentifizierungs-Backends. Setzen Sie einfach AUTHENTICATION_BACKENDS in Ihres Django-Projekts, um die Backend-Implementierungen aufzulisten, die Sie verwenden möchten. Zum Beispiel verwende ich oft eine Kombination von OpenID Authentifizierung und der Standard-Django-Authentifizierung, wie dies in meinem settings.py:

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

In diesem Beispiel wird Django zuerst versuchen, mit django.contrib.auth.backends.ModelBackend, zu authentifizieren, die der Standard-Backend von Django ist. Wenn das fehlschlägt, geht es weiter zum nächsten Backend, django_openid_auth.auth.OpenIDBackend.

Beachten Sie, dass Ihre eigene Backends auf einem Pfad sichtbar von Django sein muss. In diesem Beispiel muss ich django_openid_auth zu INSTALLED_APPS hinzufügen, sonst wird Django nicht in der Lage sein, es zu importieren und es als ein Backend zu verwenden.

Lesen Sie auch die entsprechende Dokumentation, es ist sehr schön geschrieben, leicht zu verstehen: https://docs.djangoproject.com/en/dev/topics/auth/customizing/

4

ich war, bevor sie durch dieses Problem. Dies ist der Code, den ich verwendet habe.

Dies ist die Authentifizierungs-Backend an der api/backend.py

from django.contrib.auth.models import User 


class EmailOrUsernameModelBackend(object): 

    def authenticate(self, username=None, password=None): 
     if '@' in username: 
      kwargs = {'email': username} 
     else: 
      kwargs = {'username': username} 
     try: 
      user = User.objects.get(**kwargs) 
      if user.check_password(password): 
       return user 
     except User.DoesNotExist: 
      return None 

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

Und das ist mein settings.py

AUTHENTICATION_BACKENDS = (
    'api.backend.EmailOrUsernameModelBackend', 
    'django.contrib.auth.backends.ModelBackend', 
) 

Hoffe, es hilft. Bitte sag mir, ob du immer noch in Schwierigkeiten bist. Mit diesem Code können Sie E-Mails verwenden, um den Django-Standardbenutzer selbst in Django-Administratoren zu authentifizieren.

+0

obwohl Ihre Lösung ist auch gut, aber es geht nicht genau, was ich will, werde ich meine Lösung in wenigen Stunden nach. BTW ich habe die Idee von Ihrer Lösung, also hier ist ein +1 für Sie. –

+0

Mit 'if '@' in Benutzername:' ​​zu identifizieren, ob der Benutzername eine E-Mail ist, ist eine ziemlich schlechte Möglichkeit, es zu erreichen, wenn Benutzernamen '@' enthalten können.Sie sollten zumindest den Mustervergleich verwenden oder die ausgewählte Option an der Quelle identifizieren. – vintagexav

+1

Statt 'wenn '@' Benutzername:', die 'django.core.validators.validate_email' wie folgt verwenden: ' def validateEmail (E-Mail): try: validate_email (E-Mail) return true außer Validation: return False' –

2

mehrere Backend-Authentifizierungen ist so einfach wie überzeugend. Sie müssen nur den Workflow von Django-Apps verstehen.

AUTHENTICATION_BACKENDS = (
    'django.contrib.auth.backends.Backend1', 
    'django_openid_auth.auth.Backend2', 
    ) 

Zum Beispiel haben Sie die folgenden zwei Backends definiert. Django wird zuerst zum ersten Backend gehen und Sie müssen nur ein wenig Logik in dieses Backend einfügen, so dass es, wenn es nicht mit diesem Backend in Verbindung steht, an das andere Backend weitergeleitet oder ohne Ergebnisse zurückgegeben wird. Falls keine Ergebnisse vorliegen, verschiebt django automatisch die Anfrage vom ersten Backend zum zweiten und wenn verfügbar dritten. Ich verbrachte viel Zeit damit und fand heraus, dass es nicht so komplex war.

+0

Ich verstehe nicht, warum Sie eine Antwort gepostet haben, die ziemlich genau wie meine ist, gepostet 2 Wochen zuvor ... :( – janos

+0

Eigentlich Kumpel, ich habe nicht genau das bekommen, was Sie sagen wollten, also bin ich Ihrem gefolgt antworte und habe etwas Magie von mir und Volla gemacht. Deine Antwort ist gut. Wenn du uns bei unseren Antworten beisteuerst und eine weitere auf den Boden legst, wäre das die beste Antwort auf dieses Problem. Viel Glück –

+0

Du hättest mir einen Kommentar schreiben können Ich hätte es geklärt ;-) Ich habe es jetzt geklärt, was denkst du? Lassen Sie es mich wissen, wenn Sie immer noch denken, dass es geändert werden sollte. – janos

Verwandte Themen