Djangoでメール認証をすばやく設定する方法

みなさんこんにちは!







ユーザー認証は長い間典型的なタスクでした。 Djangoは、最新のWebフレームワークと同様に、優れたユーザー認証メカニズムを備えています。

ただし、このメカニズムはデフォルトでログインを識別子として使用しますが、ログインに電子メールを使用することはすべて慣れています。







この機能を実装する必要があるとき、特にロシア語では、電子メールでの登録、確認書の送信、パスワードのリセット、その他の一般的な非常に普通のことを説明するチュートリアルはあまり多くないことがわかりました。

私はこの不正を修正することにしました。







ジャンゴ







インターネットで少し騒ぎ立てて、私の選択はdjango-user-accountsモジュールに落ちました。

このモジュールはPinaxエコシステムの一部であり、優れたドキュメントと何よりも読みやすいコードが含まれています。







モジュールは次のことができます。









設置



インストールするには、次のコマンドを実行します:







pip install django-user-accounts
      
      





requirements.txtファイルに依存関係を追加することを忘れないでください:







 django-user-accounts==2.0.3
      
      





settings.pyでINSTALLED_APPSを追加します:







 INSTALLED_APPS =[ ..... 'django.contrib.sites', 'account' ]
      
      





アカウントはモジュールに依存するため、標準サイトdangモジュールを追加することが重要です。

次に、MIDDLEWARE_CLASSESを追加します。







 MIDDLEWARE_CLASSES = [ ..... 'account.middleware.LocaleMiddleware', 'account.middleware.TimezoneMiddleware' ]
      
      





context_processors:







 TEMPLATES = [ { ..... 'OPTIONS': { 'context_processors': [ ..... 'account.context_processors.account' ], }, }, ]
      
      





一意のメールを送信して確認を要求するために、settings.pyに2つのキーを追加します。







 ACCOUNT_EMAIL_UNIQUE = True ACCOUNT_EMAIL_CONFIRMATION_REQUIRED = True
      
      





これで移行を実行できます。







 python manage.py migrate
      
      





その結果、データベースに新しいテーブルが表示されます。







 account_account account_accountdeletion account_emailaddress account_emailconfirmation account_passwordexpiry account_passwordhistory account_signupcode account_signupcoderesult django_site
      
      





以前にサイトモジュールを接続していない場合は、サイトを作成する必要があります。







 python manage.py shell >>> from django.contrib.sites.models import Site >>> site = Site(domain='localhost:8000', name='localhost:8000') >>> site.save() >>> site.id 2
      
      





そして、新しいサイトのsetting.py idに追加します。







 SITE_ID = 2
      
      





必要なページと文字のテキストのすべてのテンプレートは、 pinax-theme-bootstrapからダウンロードして、yourproject / yourapp / templates / accountに配置するだけです。







カスタマイズ



このモジュールをプロジェクトではなくDjangoアプリケーションのレベルで接続する場合、ルーティングが正しく機能するように、次の行をsettings.pyに追加します。







 ACCOUNT_LOGIN_URL = 'yourapp:account_login' ACCOUNT_EMAIL_CONFIRMATION_ANONYMOUS_REDIRECT_URL = ACCOUNT_LOGIN_URL ACCOUNT_PASSWORD_RESET_REDIRECT_URL = ACCOUNT_LOGIN_URL ACCOUNT_EMAIL_CONFIRMATION_URL = "yourapp:account_confirm_email" ACCOUNT_SETTINGS_REDIRECT_URL = 'yourapp:account_settings' ACCOUNT_PASSWORD_CHANGE_REDIRECT_URL = "yourapp:account_password"
      
      





そして、yourapp / urls.pyファイルにURLを追加します。







 urlpatterns = [ ..... url(r"^account/", include("account.urls")), ..... ]
      
      





次のアドレスが利用可能になりました。







  account/signup/ account/login/ account/logout/ account/confirm_email/<key> account/password/ account/password/reset/ account/password/reset/<token> account/settings/ account/delete/
      
      





settings.pyにメールサーバーの設定を追加することのみが残ります。







 DEFAULT_FROM_EMAIL = 'support@yoursite.ru' EMAIL_HOST = "smtp.yoursmtpserver.ru" EMAIL_PORT = 25 EMAIL_HOST_USER = "user" EMAIL_HOST_PASSWORD = "pass"
      
      





すべてを正しく行った場合、ユーザー名/パスワードを使用して指定されたURLにログインできます。アカウントを作成すると、メールを確認するためのメールがメールに送信されます。







叙情的な余談



プロジェクトではなくアプリケーションにリンクを追加した場合、パスワード回復用のリンクを正しく形成できないバグが見つかりました。

プルリクエストが受け入れられるまで、松葉杖をyourproject / urls.pyに入れることができます







 from account.views import PasswordResetTokenView urlpatterns = [ ..... url(r"^account/password/reset/(?P<uidb36>[0-9A-Za-z]+)-(?P<token>.+)/$", PasswordResetTokenView.as_view(), name="account_password_reset_token"), ..... ]
      
      





プルリクエストに新しい設定が表示されます。







 ACCOUNT_PASSWORD_RESET_TOKEN_URL = 'yourapp:account_password_reset_token'
      
      





メール認証



まず、適切なバックエンドをsettings.pyに追加します。







 AUTHENTICATION_BACKENDS = [ 'account.auth_backends.EmailAuthenticationBackend', ]
      
      





次に、登録フォームからユーザー名を削除します。このため、yourapp / forms.pyファイルに次を追加します。







 import account.forms class SignupForm(account.forms.SignupForm): def __init__(self, *args, **kwargs): super(SignupForm, self).__init__(*args, **kwargs) del self.fields["username"]
      
      





そして、yourapp / views.pyファイルでは次のとおりです。







 import yourapp.forms import account.forms import account.views class LoginView(account.views.LoginView): form_class = account.forms.LoginEmailForm class SignupView(account.views.SignupView): form_class = yourapp.forms.SignupForm def generate_username(self, form): username = form.cleaned_data["email"] return username def after_signup(self, form): # do something super(SignupView, self).after_signup(form)
      
      





ここでは、ビューについて、LoginEmailFormとSignupFormのフォームのクラスをそれぞれ定義し、必要な動作を混合できるようにafter_signupメソッドを再定義します。 デフォルトでは、ユーザー名フィールドはメールに設定されています。







ファイルyourapp / urls.pyでURLを再定義するだけです。







 from . import views urlpatterns = [ ..... url(r"^account/login/$", views.LoginView.as_view(), name="account_login"), url(r"^account/signup/$", views.SignupView.as_view(), name="account_signup"), url(r"^account/", include("account.urls")), ..... ]
      
      





account.urlsを接続する前にカスタムビューの呼び出しを行う必要があることに注意してください。そうしないと、再定義されません。







古いデータの移行



現在のユーザーがログインできるようにするには、メールアドレスをaccount_emailaddressテーブルに追加します。







 insert into account_emailaddress(email, verified, "primary", user_id) select au.email, True, True, au.id from auth_user au where au.email is not null
      
      





この場合、検証済みフィールドにtrueが挿入されます。 すぐに確認します。







すべてのユーザーがアカウントを持つために、アカウントaccount_accountに記入します。







 insert into account_account (timezone, "language", user_id) select '','ru', id from auth_user
      
      





おわりに



django-user-accountモジュールの詳細については、 公式ドキュメントをご覧ください。

ソースコードはこちらです。 Djangoの認証メカニズムがどのように機能するかをよりよく理解するために、それを読むことは役に立ちます。







この記事が時間の節約に役立つことを願っています。 使用するツールをコメントで共有してください。








All Articles