3

システムでモデルを作成した別のデータベースにクエリを実行するカスタム バックエンドをセットアップしようとしています。独自のルール (ユーザー名の代わりに電子メール、別の方法でソルト化/ハッシュ化されたパスワード) を使用するため、組み込みの認証を使用できません。次のようにカスタム認証バックエンドを設定しました。

class BlahBlahBackend:

    def check_password():
        # check password code here
        return true

    def authenticate(self, email=None, password=None):
        import myapp.models.loginmodel
        try:
            person =  myapp.models.loginmodel.People.objects.get(email=email)
            if check_password(password, person.password):
                try:
                    user = User.objects.get(email=email)
                except User.DoesNotExist:
                    username=person.first_name + person.last_name
                    name_count = User.objects.filter(username__startswith = username).count()
                    if name_count:
                        username = '%s%s'%(username, name_count + 1)
                        user = User.objects.create_user(username,email)
                    else:
                        user = User.objects.create_user(username,email)
        except People.DoesNotExist:
            return None

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

BlahBlahBackend を認証バックエンドとして追加しました。

AUTHENTICATION_BACKENDS = ('django.contrib.auth.backends.ModelBackend', 'socialauth.auth_backends.OpenIdBackend', 'socialauth.auth_backends.TwitterBackend', 'socialauth.auth_backends.FacebookBackend', 'socialauth.auth_backends.BlahBlahBackend', )

ご覧のとおり、socialauth にもある既存の認証バックエンドもいくつか使用しています。

次のビューを指す送信フォームがあります。

def blahblah_login_complete(request):
    email = request.POST.get('email')
    password = request.POST.get('password')
    user = authenticate(email,password)
    # if user is authenticated then login user
    if user:
        login(request, user)
    else:
        return HttpResponseRedirect(reverse('socialauth_login_page'))

ただし、この方法でログインしようとすると、他のバックエンドの 1 つ以上が、その方法を使用してログインしようとしているかのように動作しているように見えます。

バックエンドがキャッシュされていることを読んだので、実行しました

Session.objects.all().delete()

バックエンドのキャッシュをクリアします。

私の主な質問は次のとおりです。

  1. AUTHENTICATION_BACKENDS にリストされているアイテムの順序
  2. システムはどのバックエンドを使用するかをどのように決定/認識しますか? これはどのドキュメントでも明確にされておらず、少し混乱しています。
  3. リクエストに基づいて特定の承認の使用を強制する方法はありますか? つまり、誰かがフォームを送信した場合、openid または Twitter 経由のログインではなく、フォーム ログイン ベースの認証を強制的に使用する方法はありますか?

アップデート:

できます!これはとてもクールです、ありがとう。django のドキュメントが「他に何もする必要はありません。魔法のように機能するだけです」と言っていたように思えたのですが、これは絶対に当てはまることがわかりました。バックエンドが存在し、資格情報が正しく設定されている限り、認証は機能します。実際の問題は、urls.py ファイルの構成ミスで、ログイン フォームから正しいハンドラーに投稿が送信されなかったことが判明したため、別の認証方法を使用しようとし続けました。

4

3 に答える 3

1

django.contrib.auth.authenticate()にキーワード引数を使用することになっています。名前は、バックエンドのauthenticateメソッドの引数の名前と一致する必要があります。デフォルトのバックエンドは、「username」および「password」という名前を処理します。

バックエンドでは、キーワード引数に別の名前を使用できます(例:blahblah_emailとblahblah_password)。次に、authenticate(blahblah_email = ...、blahblah_password = ...)を呼び出します。

于 2010-01-28T09:24:53.797 に答える
1
  1. ここで明確に説明されています-djangoは、定義された順序で各バックエンドを試行します。最初に認証に失敗した場合は、2番目に進みます。

  2. バックエンドクラスを動的にロードし、それを介して直接認証できると思います。その方法については、django authenticate()関数のソースを参照してください。

于 2010-01-28T09:11:50.520 に答える
1

django-casが参考になると思います :)

はい、AUTHENTICATION_BACKENDS の順序は重要です。

authenticateDjango はバックエンド リストをループし、渡された資格情報パラメーターを受け入れるメソッドを持つ最初のバックエンドで停止します。

于 2010-01-28T15:32:16.467 に答える