Sassyブログ

埼玉県在住のシステムエンジニアです。基本的にはIT技術関連の内容を中心に発信していきます。たまにゲーム関連ネタも載せます

DjangoからGmailでメール送信する場合はアプリパスワードを発行しよう

f:id:y_saiki:20171024233602j:plain

今回はdjangoアプリからメール送信でgmailsmtpサーバーを使うときのベストプラクティスな設定方法を書こうと思います。

環境

  • Django3.1
  • Python3.8

GmailはGoogleWorkspaceで設定している会社ドメインのメールアドレスを使用しています。

djangoドキュメントにも記載があるように、メール送信する際にはdjango.core.mailモジュールを読み込んでsend_mail関数をインポートして使います。

docs.djangoproject.com

from djnago.core.mail import send_mail

このモジュールを使えば環境変数EMAIL_HOSTEMAIL_HOST_PASSWORDEMAIL_HOST_USEREMAIL_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アカウントのデフォルトの設定では「安全性の低いアプリの許可」がオフになっているからです。

support.google.com

ここで初学者の方はあまりピンとこない方がいるかと思うので補足すると、

Googleアカウントを使用してログインしているのはユーザー本人ではないということです。

アプリケーションがGoogleアカウントの認証情報を使用してログインを行おうとしています。

そのため、「安全性の低いアプリの許可」がオフになっていると、ユーザーがブラウザからGmailを開いてログインしてメールを扱うことはできますが、アプリケーションからログインしてメールを扱うことはできないのです。

これを解決するためには、2通りの方法があります。

1.「安全性の低いアプリの許可」がオンにする 2.アプリパスワードを使用する

もう自明ですが、(1)はセキュリティの観点からは一番危険です。

アカウント情報が知られるとプログラムから好き勝手にメールを扱うことができてしまうので好ましくないです。

なのでアプリパスワードを使用してください。

このアプリパスワードをEMAIL_HOST_PASSWORDへ設定することでDjangoアプリからgmailsmtpを利用してメール送信を行うことができます。

ただし、アプリパスワードは2段階認証を有効にしていないと設定できないので2段階認証を有効にしてください。

以下はgmailSMTPサーバー情報の設定値です。

細かい部分は省きます。

[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ファイルに設定しておくとよいです。