13

まとめ

Django + MongoEngine でカスタム User モデルカスタム認証バックエンド (電子メール/パスワード認証を可能にする)を使用するにはどうすればよいですか? (そのためにもカスタム バックエンドが必要ですか? ...つまり、MongoEngine で認証するときにユーザー名に電子メールを使用するためです。)

Django で認証するときに、 Mongoをプライマリ データストアとして使用しながら、カスタム ユーザー オブジェクトを使用する簡単な (そして完全な!) 例を含むドキュメントはありますか? (Postgres には、より明確で包括的なドキュメントがあります...)


詳細

MongoEngine は、「クラシック」(別名 ' mongoengine.django.auth.MongoEngineBackend ') の方法...または... 「カスタム ユーザー モデル」(別名 ' django.contrib.auth ') の 2 種類の認証しか提供しないようです。 .backends.ModelBackend ') 方法-どちらも、次の別の質問に対する Nicolas Cortot の回答で多かれ少なかれ簡潔に概説されています:

Python-Social-Auth fails with mongoEngine (Django)

これらの認証手法はどちらも、Django の AbstractBaseUser クラスに似たauthenticate()メソッド ( check_password関数に依存するメソッド) へのアクセスを提供します。ただし、いわゆる「カスタムユーザーモデル」フレーバーの認証を使用すると(上記のリンクで概説されているように) 、それをカスタムバックエンドペアにします(ユーザー名に電子メールを使用するため)...通常の authenticate() 関数にアクセスできないため、問題が発生します。

たとえば、そのように...

accounts.models.py


# ...postgres では、AbstractBaseUser をサブクラス化しますが、Mongo では...(?)

django.confのインポート設定から
from mongoengine.fields import EmailField, BooleanField
from mongoengine.django.auth import ユーザー クラス MyUser(ユーザー): email = EmailField(max_length=254, unique=True) is_active = BooleanField (デフォルト = True) is_admin = BooleanField (デフォルト = False) USERNAME_FIELD = 'メール' REQUIRED_FIELDS = '' ...

my_custom_backend.py

# ...認証にユーザー名の代わりに電子メールを使用するには、カスタム バックエンドが必要ですか?

django.confのインポート設定から
django.contrib.auth.models import check_password から
#from mongoengine.django.auth import check_password
#from django.contrib.auth.hashers import check_password
モデルから MyUser をインポート

    クラス EmailAuthBackend(オブジェクト):

        デフ認証 (自己、電子メール = なし、パスワード = なし):

# ...ああ、私は既存の authenticate() で通常のバックエンドを使用していないので
# メソッドの場合、利用可能なネイティブの check_password() 関数はありません。ハッシュする必要があることを意味します
# パスワードなど

したがって、一見、私は独自の check_password 関数を作成する必要があります。PostgreSQL 認証で通常見られるAbstractBaseUserクラスに固有のすべての利点を得るには、カスタム User モデルを完全に膨らませる必要があります。

ここで完全に混乱していますか?...つまり、MongoEngine を使用するときに認証にユーザー名の代わりに電子メールを使用したい場合、カスタム バックエンドを使用する必要は実際にはまったく不要ですか?

認証に関して、Django が MongoEngine とどのように連携するかについて、また、カスタム ユーザー オブジェクトをモデル化して呼び出した方法と、そのプロセス中の MongoEngine のユーザー オブジェクトの特定のサブクラス化について、根本的な誤解をしているように感じます...

なぜなら、現在のところ、ブラウザに「'AnonymousUser' object has no attribute 'backend'」というエラー メッセージが表示されるからです。また、この問題は予期しない理由で発生する場合があることにも注意しました。たとえば、authenticate() メソッドがハッシュ化されたパスワードを予期していたり​​、ログイン (電子メール) が長すぎるためなどです。この後者の状況が当てはまる可能性があるその他の例については、以下を参照してください。

Django登録フォーム「AnonymousUser」オブジェクトには属性「backend」がありません


設定.py

INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django.contrib.admin',
    'mongoengine.django.mongo_auth',
    'アカウント',
)

AUTHENTICATION_BACKENDS = (
    'mongoengine.django.auth.MongoEngineBackend',
    #'accounts.my_custom_backend.EmailAuthBackend',
    #'django.contrib.auth.backends.ModelBackend',
)

AUTH_USER_MODEL = 'mongo_auth.MongoUser'
MONGOENGINE_USER_DOCUMENT = 'accounts.models.User'

accounts.views.py

django.contrib.authから、django_loginとしてログインをインポートします
from my_custom_backend import EmailAuthBackend
from フォーム インポート AuthenticationForm

デフログイン(リクエスト):

    form = AuthenticationForm(data=request.POST)
    form.is_valid() の場合:
        試す:
            バックエンド = EmailAuthBackend()
            user = backend.authenticate(email=request.POST['email'], password=request.POST['password'])
            django_login(リクエスト、ユーザー)
            リダイレクトを返す('/')
        DoesNotExist を除く:
            return HttpResponse('ユーザーが存在しません')
    そうしないと:
        フォーム = 認証フォーム()

    return render_to_response('accounts/login.html',
       { 'フォーム': フォーム},
       context_instance=RequestContext(リクエスト))
4

2 に答える 2