Friday, October 6, 2023

Configuring email sending through Django

Now that the register user API end point is ready and tested, the next step is to send the verification email where the user will click on a link to verify his or her email. Before going into the nature of the verification link, the first step is to configure email sending through Django.

Django comes with the django.core.mail package with the send_mail method. So no additional packages are needed. This needs a few additional configurations in the email client that the admin (in this case me) will be using and also in the Django settings.py file. I am using my Gmail client. For this, I needed to go to “Manage your Google Account” and in there to go to the “Security” section. Here, one needs to turn on “2-step Verification”. In reality, the be able to use the client does not have anything to do with 2-step verification, but the option to create passwords for third party apps lies within this option. Way at the bottom of this 2-step verification section, there is “App passwords”. Here one needs to create an app and it will provide a password. This password is what will be used by Django for sending emails through the client.

The additional settings in settings.py file are:
# Email settings
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = KEYS.EMAIL_HOST
EMAIL_HOST_USER = KEYS.EMAIL_USERNAME
EMAIL_HOST_PASSWORD = KEYS.EMAIL_PASSWORD
EMAIL_PORT = KEYS.EMAIL_PORT
EMAIL_USE_TLS = True
DEFAULT_FROM_EMAIL = KEYS.EMAIL_FROM_USERNAME
Since the settings are sensitive or variable, it is best to import them from the environment which for now is merely an env.py file until this app gets deployed. The keys are:
# Email settings
EMAIL_HOST = 'email-host'   # for gmail - 'smtp.gmail.com'
EMAIL_USERNAME = 'username'
EMAIL_FROM_USERNAME = 'from-username'   # can be same as username
EMAIL_PASSWORD = 'password'   # set app-password in Security of Google account
EMAIL_PORT = 123              # 587 for SMTP if using google

These entries are from env_example.py file which describes the keys that need to be added to env.py file. The examples are specified for Gmail though other clients can also offer similar features.

With this done, all that needs to be done is call the send_mail method. Instead of calling it from RegisterUserView class in views.py file, it would be better to place this code in a utility method defined in a file utils.py file in user_auth module. This would only make it easier to test and mock the method in tests.

def send_verification_link_email(username):
    '''Send an email to newly registered used with verification link'''

    message_body = (
        "Hello,\n"
        "Thank you for registering with Online Edu!\n"
        "\n"
        "You are not yet ready to use your account.
        Before you can login to the website,
        please verify your email by clicking on this link:\n"
        "http://www.google.com \n"
        "\n"
        "Please click on this link within 15 minutes of receiving this email.\n"
        "\n"
        "Thank you,\n"
        "Online Edu"
    )

    send_mail(
        subject='Verification link',
        message=message_body,
        from_email=settings.DEFAULT_FROM_EMAIL,
        recipient_list=[username]
    )

As of now the verification link is a dummy link that has been inserted. The next step will be to use JSON Web Tokens to create a token and then a link with that token.

But before that, the tests need to be updated as sending email should not happen during tests and this method should be mocked.

No comments:

Post a Comment