今回はdjangoアプリからメール送信でgmailのsmtpサーバーを使うときのベストプラクティスな設定方法を書こうと思います。
環境
- Django3.1
- Python3.8
GmailはGoogleWorkspaceで設定している会社ドメインのメールアドレスを使用しています。
djangoドキュメントにも記載があるように、メール送信する際にはdjango.core.mail
モジュールを読み込んでsend_mail
関数をインポートして使います。
from djnago.core.mail import send_mail
このモジュールを使えば環境変数にEMAIL_HOST
、EMAIL_HOST_PASSWORD
、EMAIL_HOST_USER
、EMAIL_PORT
などを書いていくとdjangoがメール送信時にその環境変数を使ってメールサーバーへ接続してくれます。
ここで重要なのがEMAIL_HOST_PASSWORDへ設定する値です。
普通に設定するとGoogleアカウントのパスワードを設定してしまいますが、デフォルトのGoogleアカウント設定だと上手くいきません。
恐らくアプリ側でこのようなエラーが吐かれると思います。
Username and Password not accepted. Learn more at\n5.7.8 https://support.google.com/mail/?p=BadCredentials w123sm11946588pff.186 - gsmtp
なぜならGoogleアカウントのデフォルトの設定では「安全性の低いアプリの許可」がオフになっているからです。
ここで初学者の方はあまりピンとこない方がいるかと思うので補足すると、
Googleアカウントを使用してログインしているのはユーザー本人ではないということです。
アプリケーションがGoogleアカウントの認証情報を使用してログインを行おうとしています。
そのため、「安全性の低いアプリの許可」がオフになっていると、ユーザーがブラウザからGmailを開いてログインしてメールを扱うことはできますが、アプリケーションからログインしてメールを扱うことはできないのです。
これを解決するためには、2通りの方法があります。
1.「安全性の低いアプリの許可」がオンにする 2.アプリパスワードを使用する
もう自明ですが、(1)はセキュリティの観点からは一番危険です。
アカウント情報が知られるとプログラムから好き勝手にメールを扱うことができてしまうので好ましくないです。
なのでアプリパスワードを使用してください。
このアプリパスワードをEMAIL_HOST_PASSWORDへ設定することでDjangoアプリからgmailのsmtpを利用してメール送信を行うことができます。
ただし、アプリパスワードは2段階認証を有効にしていないと設定できないので2段階認証を有効にしてください。
細かい部分は省きます。
[app_name]/settings.py
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' EMAIL_HOST = 'smtp.gmail.com' EMAIL_HOST_PASSWORD = [<b>アプリパスワード</b>] EMAIL_HOST_USER = [メールアドレス: (例)hoge@example.com] EMAIL_PORT = 587 EMAIL_USE_TLS = True ・・・省略
EMAIL_BACKEND
は設定しなくてもDjangoがデフォルトで「django.core.mail.backends.smtp.EmailBackend」の値を使用してくれます。
ちなみに本番運用時はEMAIL_HOST_PASSWORDとEMAIL_HOST_USERの値はOSの環境変数や.envファイルに設定しておくとよいです。