悩んでいること
お世話になります。藤田と申します。
下記 Qiita の記事に記載のとおり、dj_rest_auth を使って JWT 認証によるログイン・ログアウトなどの基本的な機能を実装することができました。
REST 化した Django の JWT 認証を dj_rest_auth に丸投げする
https://qiita.com/hajime-f/items/0b42fa3233e41a0f691d
次に、ユーザー登録の機能も dj_rest_auth に丸投げしたいと考えて、dj_rest_auth.registration を settings.py の INSTALLED_APPS に追加しました。
ところが、これを追加すると、正しく動いていたはずのログイン・ログアウトなどの機能が、「EmailAddress matching query does not exist」の例外送出により、うまく動かなくなります。
動作環境
- 環境
Ubuntu Server 20.04.1 LTS
Docker 19.03.13
Docker Compose 1.27.3
- パッケージ
Django 3.1.4
djangorestframework 3.12.2
djangorestframework-simplejwt 4.6.0
dj-rest-auth 2.1.2
django-allauth 0.44.0
ソースコード
GitHub:https://github.com/hajime-f/octave
settings
1INSTALLED_APPS = [ 2 'django.contrib.admin', 3 'django.contrib.auth', 4 'django.contrib.contenttypes', 5 'django.contrib.sessions', 6 'django.contrib.messages', 7 'django.contrib.staticfiles', 8 'django.contrib.sites', 9 10 # 3rd party apps 11 'rest_framework', 12 'rest_framework.authtoken', 13 'allauth', 14 'allauth.account', 15 'dj_rest_auth', 16 'dj_rest_auth.registration', #### これを追加 17 18 #My applications 19 'users', 20] 21 22REST_FRAMEWORK = { 23 'DEFAULT_AUTHENTICATION_CLASSES': ( 24 'dj_rest_auth.jwt_auth.JWTCookieAuthentication', 25 ) 26} 27SITE_ID = 1 28REST_USE_JWT = True 29EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' 30JWT_AUTH_COOKIE = 'user' 31AUTH_USER_MODEL = 'users.User' 32 33SIMPLE_JWT = { 34 'USER_ID_FIELD': 'uuid', 35} 36 37ACCOUNT_AUTHENTICATION_METHOD = 'email' 38ACCOUNT_USERNAME_REQUIRED = False 39ACCOUNT_USER_MODEL_USERNAME_FIELD = None 40ACCOUNT_EMAIL_REQUIRED = True 41ACCOUNT_UNIQUE_EMAIL = True 42ACCOUNT_EMAIL_VERIFICATION = 'mandatory' 43LOGIN_REDIRECT_URL = '/' 44ACCOUNT_LOGOUT_REDIRECT_URL = '/'
urls
1urlpatterns = [ 2 path('admin/', admin.site.urls), 3 path('dj-rest-auth/', include('dj_rest_auth.urls')), 4 path('dj-rest-auth/registration/', include('dj_rest_auth.registration.urls')), #### これを追加 5]
上記の「これを追加」をコメントアウト(削除)すると、ログイン・ログアウトなどの機能は、正しく動作します。
現象詳細
/dj-rest-auth/login/ にはアクセスできます。
しかし、この状態で「POST」すると、次の例外が出ます。
なお、settings.py の INSTALLED_APPS から dj_rest_auth.registration をコメントアウトすると、この例外は出なくなり、正しく JWT の token が返ってきます。
また、/dj-rest-auth/registration/ にもアクセスできます。
メールアドレス・パスワード・パスワード確認を入力すると、ユーザーが正しく仮登録されていることが admin 画面から確認できます。
(現状ではアドレス検証用のメールが飛ばず、本登録まで完結しないのですが……これは EmailBackend の話で、今回の質問とは趣旨が違うと思うので割愛いたします)
Environment: Request Method: POST Request URL: http://127.0.0.1:8081/dj-rest-auth/login/ Django Version: 3.1.4 Python Version: 3.9.1 Installed Applications: ['django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'django.contrib.sites', 'rest_framework', 'rest_framework.authtoken', 'allauth', 'allauth.account', 'allauth.socialaccount', 'dj_rest_auth', 'dj_rest_auth.registration', 'users'] Installed Middleware: ['django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware'] Traceback (most recent call last): File "/usr/local/lib/python3.9/site-packages/django/core/handlers/exception.py", line 47, in inner response = get_response(request) File "/usr/local/lib/python3.9/site-packages/django/core/handlers/base.py", line 179, in _get_response response = wrapped_callback(request, *callback_args, **callback_kwargs) File "/usr/local/lib/python3.9/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view return view_func(*args, **kwargs) File "/usr/local/lib/python3.9/site-packages/django/views/generic/base.py", line 70, in view return self.dispatch(request, *args, **kwargs) File "/usr/local/lib/python3.9/site-packages/django/utils/decorators.py", line 43, in _wrapper return bound_method(*args, **kwargs) File "/usr/local/lib/python3.9/site-packages/django/views/decorators/debug.py", line 89, in sensitive_post_parameters_wrapper return view(request, *args, **kwargs) File "/usr/local/lib/python3.9/site-packages/dj_rest_auth/views.py", line 48, in dispatch return super(LoginView, self).dispatch(*args, **kwargs) File "/usr/local/lib/python3.9/site-packages/rest_framework/views.py", line 509, in dispatch response = self.handle_exception(exc) File "/usr/local/lib/python3.9/site-packages/rest_framework/views.py", line 469, in handle_exception self.raise_uncaught_exception(exc) File "/usr/local/lib/python3.9/site-packages/rest_framework/views.py", line 480, in raise_uncaught_exception raise exc File "/usr/local/lib/python3.9/site-packages/rest_framework/views.py", line 506, in dispatch response = handler(request, *args, **kwargs) File "/usr/local/lib/python3.9/site-packages/dj_rest_auth/views.py", line 138, in post self.serializer.is_valid(raise_exception=True) File "/usr/local/lib/python3.9/site-packages/rest_framework/serializers.py", line 220, in is_valid self._validated_data = self.run_validation(self.initial_data) File "/usr/local/lib/python3.9/site-packages/rest_framework/serializers.py", line 422, in run_validation value = self.validate(value) File "/usr/local/lib/python3.9/site-packages/dj_rest_auth/serializers.py", line 131, in validate self.validate_email_verification_status(user) File "/usr/local/lib/python3.9/site-packages/dj_rest_auth/serializers.py", line 112, in validate_email_verification_status email_address = user.emailaddress_set.get(email=user.email) File "/usr/local/lib/python3.9/site-packages/django/db/models/manager.py", line 85, in manager_method return getattr(self.get_queryset(), name)(*args, **kwargs) File "/usr/local/lib/python3.9/site-packages/django/db/models/query.py", line 429, in get raise self.model.DoesNotExist( Exception Type: DoesNotExist at /dj-rest-auth/login/ Exception Value: EmailAddress matching query does not exist.
仮説
下記 Qiita の記事に記載のとおり、AbstractBaseUser を継承したカスタムユーザーで E-mail のみ(ユーザー名が不要)でログインできるように実装しています。
AbstractBaseUser を継承したカスタムユーザーで E-mail ログインを実現する
https://qiita.com/hajime-f/items/c2f02306556c1ea16e5c
いまのところ、ここに原因があるのでは……となんとなく考えているのですが、検証の方法が分かりません。
相談したいこと
- dj_rest_auth で実現できたログイン・ログアウトなどの機能が、dj_rest_auth.registration を追加すると、「EmailAddress matching query does not exist」の例外送出により、うまく動かなくなる原因として、何が考えられるでしょうか?
- 原因を特定して、これを修正するための方法として、何が考えられるでしょうか?
よろしくお願い致します。
あなたの回答
tips
プレビュー