2013-06-12 14 views
9

ここに深刻な助けが必要です。Django複数の認証バックエンド、1つのプロジェクト、どのように?

私はdjango/pythonで書かれたアプリケーションを持っています。このアプリケーションでは、これを拡張して「アプリ」として他のソリューションを含める必要があります。 たとえば、統合する私のアプリケーションの名前は "my_new_app" ここでメインアプリケーション用に書かれたバックエンド認証があり、私はそれを使うことができません。 私はmysql dbからクエリを受け取り、メインアプリケーションはcassendraとredisを主に使用します。 私の質問は、新しいアプリケーション "my_new_app"に別の認証バックエンドを使用して、両方を同じドメインで実行できる方法はありますか? 質問は明らかではないかもしれませんが、質問があれば明確にします。

答えて

24

に複数の認証バックエンドがあります。 Djangoプロジェクトのsettings.pyAUTHENTICATION_BACKENDSを設定して、使用するバックエンドの実装をリストアップしてください。例えば、私は頻繁に私settings.pyでこのように、OpenID認証と標準Djangoの認証を組み合わせて使用​​します。

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

この例では、Djangoは最初のDjangoのデフォルトのバックエンドである、django.contrib.auth.backends.ModelBackendを使用して認証しようとします。失敗した場合は、次のバックエンドdjango_openid_auth.auth.OpenIDBackendに移動します。

カスタムバックエンドは、Djangoが認識できるパスにある必要があります。この例では、django_openid_authINSTALLED_APPSに追加する必要があります。そうでなければ、Djangoはそれをインポートしてバックエンドとして使用できません。

また理解しやすい、それは非常にうまく書かれている、関連文書をお読みください。 https://docs.djangoproject.com/en/dev/topics/auth/customizing/

4

私は前にこの問題を進めてきました。これは私が使用したコードです。

これは、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 

での認証バックエンドであり、これは私のsettings.py

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

ですが、それがお役に立てば幸いです。まだ困っている場合は教えてください。このコードを使用すると、Django管理者であっても電子メールを使ってデフォルトのDjangoユーザーを認証することができます。

+0

あなたのソリューションも良いですが、私が欲しいものを正確に扱っていないのですが、私は数時間で私のソリューションを投稿します。私はあなたのソリューションからアイデアを得ましたので、ここにあなたに+1があります。 –

+0

ユーザ名に '@ 'を含めることができれば、ユーザ名が電子メールかどうかを識別するために' if' @ 'を使用することは、それを達成するためのかなり悪い方法です。少なくとも、パターンマッチングを使用するか、ソースで選択したオプションを特定する必要があります。 – vintagexav

+1

代わりに 'ユーザ名での '@' 場合: 'デフvalidateEmail(電子メール): 試し: validate_email(電子メール)ValidationErrorを除く リターン真 : '、このような' django.core.validators.validate_email'を使用返信False' –

2

複数のバックエンド認証を使用することは、パイと同じくらい簡単です。 Djangoのアプリケーションのワークフローを理解するだけで済みます。

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

たとえば、次の2つのバックエンドが定義されています。 Djangoはまず最初のバックエンドに行き、そのバックエンドに関係のないものがあれば、それを他のバックエンドに転送するか、何の結果も返さないようにバックエンドにロジックを入れるだけです。結果が得られない場合、djangoは最初のバックエンドから2番目のバックエンドにリクエストを自動的にシフトします。 私はこれに多くの時間を費やし、それが複雑ではないことを知りました。

+0

2週間前に投稿された回答と同じものを投稿した理由は分かりません。: – janos

+0

実際にあなたが言ったことはまったくありませんでした。あなたが私たちの答えの両方に参加し、もう1つを底に置くと、この問題に関する最良の答えになります。幸運 –

+0

あなたは私にコメントを落としている可能性があります、私は明確にしただろう;-)私は今それを明確にした、あなたはどう思いますか?あなたがまだそれを修正すべきだと思ったら教えてください。 – janos

関連する問題