2013-06-12 15 views
9

Hai bisogno di aiuto serio qui.Django Multiple Authentication Backend per un progetto, COME?

Ho un'applicazione scritta in django/python e devo estenderla e includere qualche altra soluzione come "app" in questa applicazione. Ad esempio, la mia app da integrare si chiama "my_new_app" Ora c'è un'autenticazione di backend scritta per l'applicazione principale e non posso usarla. Ho un mysql db da cui eseguire la query e l'app principale utilizza principalmente cassendra e redis. Quindi la mia domanda è, c'è un modo per utilizzare un back-end di autenticazione separato per la nuova app "my_new_app" ed eseguire entrambi nello stesso dominio? La domanda potrebbe non essere chiara, chiarirò se richiesto.

risposta

24

È possibile disporre di più back-end di autenticazione. Basta impostare lo AUTHENTICATION_BACKENDS nel settings.py del tuo progetto Django per elencare le implementazioni back-end che desideri utilizzare. Per esempio io uso spesso una combinazione di autenticazione OpenID e l'autenticazione standard Django, come questo nel mio settings.py:

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

In questo esempio Django prima cercherà di autenticare usando django.contrib.auth.backends.ModelBackend, che è il backend predefinito di Django. Se fallisce, passa al prossimo backend, django_openid_auth.auth.OpenIDBackend.

Nota che i tuoi backend personalizzati devono trovarsi su un percorso visibile da Django. In questo esempio devo aggiungere django_openid_auth a INSTALLED_APPS, altrimenti Django non sarà in grado di importarlo e usarlo come back-end.

Leggi anche la relativa documentazione, è molto ben scritto, facile da capire: https://docs.djangoproject.com/en/dev/topics/auth/customizing/

4

che ho passato questo problema prima. Questo è il codice che ho usato.

Questo è il backend di autenticazione al 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 

E questo è il mio settings.py

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

Speranza che aiuta. Per favore, dimmi se sei ancora nei guai. Questo codice ti consentirà di utilizzare la posta elettronica per autenticare l'utente Django predefinito anche nell'amministratore di Django.

+0

anche se la soluzione è buona ma non risponde esattamente a ciò che voglio, pubblicherò la mia soluzione in poche ore. BTW ho avuto l'idea dalla tua soluzione quindi ecco un +1 per te. –

+0

Usando 'if '@' nel nome utente:' per identificare se il nome utente è un'e-mail è un modo piuttosto brutto per ottenerlo se i nomi utente possono contenere '@'.Dovresti almeno usare la corrispondenza del modello o identificare l'opzione scelta all'origine. – vintagexav

+1

Invece 'se '@' Nome utente:', utilizzare i 'django.core.validators.validate_email' come questo: ' def validateEmail (e-mail): prova: validate_email (e-mail) ritorno vero tranne ValidationError: return False' –

2

L'utilizzo di più autenticazioni di backend è semplice come una torta. Hai solo bisogno di capire il flusso di lavoro delle app Django.

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

Ad esempio sono definiti i due seguenti backend. Django andrà per la prima volta al primo backend e dovrai solo mettere un po 'di logica in quel backend in modo che, se non è collegato a quel backend, venga inoltrato all'altro backend o restituito senza risultati. In caso di assenza di risultati, django trasferirà automaticamente la richiesta dal primo back-end al secondo e, se disponibile, dal terzo. Trascorro molto tempo su questo e ho scoperto che non era così complesso.

+0

Non capisco perché hai postato una risposta che è praticamente la mia, pubblicata 2 settimane prima ... :( – janos

+0

In realtà non ho capito esattamente cosa volevi dire, quindi ho seguito il tuo rispondi e fai un po 'di magia mia e di volla La tua risposta è buona.Se ti unisci a entrambe le nostre risposte e ne metti un'altra in fondo sarebbe la migliore risposta a questo problema. Buona fortuna –

+0

Avresti potuto lasciarmi un commento , Avrei chiarito ;-) L'ho chiarito ora, cosa ne pensi? Fammi sapere se pensi ancora che dovrebbe essere modificato. – janos

Problemi correlati