Skip to main content

Email confirmation app for django

Project description

Django Email Verification

PyPI PyPI - License GitHub Workflow Status codecov

icon

Do you like my work and want to support me?

Buy Me A Coffee

🚧 Work in progress 🚧

The package now also provides all the feature needed for password recovery, but the documentation is not ready yet.
Thanks for your patience!

Requirements

  • Python >= 3.8
  • Django >= 3.1

General concept

Schema

Installation

You can install by:

pip3 install django-email-verification

and import by:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    ...
    'django_email_verification',  # you have to add this
]

Settings parameters

You have to add these parameters to the settings, you have to include all of them except the last one:

def verified_callback(user):
    user.is_active = True


EMAIL_VERIFIED_CALLBACK = verified_callback
EMAIL_FROM_ADDRESS = 'noreply@aliasaddress.com'
EMAIL_MAIL_SUBJECT = 'Confirm your email'
EMAIL_MAIL_HTML = 'mail_body.html'
EMAIL_MAIL_PLAIN = 'mail_body.txt'
EMAIL_TOKEN_LIFE = 60 * 60
EMAIL_PAGE_TEMPLATE = 'confirm_template.html'
EMAIL_PAGE_DOMAIN = 'http://mydomain.com/'
EMAIL_MULTI_USER = True  # optional (defaults to False)

# For Django Email Backend
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_PORT = 587
EMAIL_HOST_USER = 'mymail@gmail.com'
EMAIL_HOST_PASSWORD = 'mYC00lP4ssw0rd'  # os.environ['password_key'] suggested
EMAIL_USE_TLS = True

In detail:

  • EMAIL_VERIFIED_CALLBACK: the function that will be called when the user successfully verifies the email. Takes the user object as argument.
  • EMAIL_FROM_ADDRESS: this can be the same as EMAIL_HOST_USER or an alias address if required.
  • EMAIL_MAIL_:
    • SUBJECT: the mail default subject.
    • HTML: the mail body template in form of html.
    • PLAIN: the mail body template in form of .txt file.
  • EMAIL_TOKEN_LIFE: the lifespan of the email link (in seconds).
  • EMAIL_PAGE_TEMPLATE: the template of the success/error view.
  • EMAIL_PAGE_DOMAIN: the domain of the confirmation link (usually your site's domain).
  • EMAIL_MULTI_USER: (optional) if True an error won't be thrown if multiple users with the same email are present ( just one will be activated)

For the Django Email Backend fields look at the official documentation.

The EMAIL_VERIFIED_CALLBACK can be a function on the AUTH_USER_MODEL, for example:

EMAIL_VERIFIED_CALLBACK = get_user_model().verified_callback

The function will receive no arguments.

Templates examples

The EMAIL_MAIL_SUBJECT should look like this ({{ link }}(str), {{ expiry }}(datetime) and user(Model) are passed during the rendering):

EMAIL_MAIL_SUBJECT = 'Confirm your email {{ user.username }}'

The EMAIL_MAIL_HTML should look like this ({{ link }}(str), {{ expiry }}(datetime) and user(Model) are passed during the rendering):

<h1>You are almost there, {{ user.username }}!</h1><br>
<h2>Please click <a href="{{ link }}">here</a> to confirm your account</h2>
<h2>The token expires on {{ expiry|time:"TIME_FORMAT" }}</h2>

The EMAIL_MAIL_PLAIN should look like this ({{ link }}(str), {{ expiry }}(datetime) and user(Model) are passed during the rendering):

You are almost there, {{ user.username }}!
Please click the following link to confirm your account: {{ link }}
The token expires on {{ expiry|time:"TIME_FORMAT" }}

The EMAIL_PAGE_TEMPLATE should look like this ({{ success }}(bool), {{ user }}(Model) and {{ request }}(WSGIRequest) are passed during the rendering):

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Confirmation</title>
</head>
<body>
{% if success %}
{{ user.username }}, your account is confirmed!
{% else %}
Error, invalid token!
{% endif %}
</body>
</html>

Email sending

After you have created the user you can send the confirm email

from django.shortcuts import render
from django.contrib.auth import get_user_model
from django_email_verification import send_email


def my_functional_view(request):
    ...
    user = get_user_model().objects.create(username=username, password=password, email=email)
    user.is_active = False  # Example
    send_email(user)
    return render(...)

send_email(user) sends an email with the defined template (and the pseudo-random generated token) to the user.

IMPORTANT: You have to manually set the user to inactive before sending the email.

If you are using class based views, then it is necessary to call the superclass before calling the send_confirm method.

from django.views.generic.edit import FormView
from django_email_verification import send_email


class MyClassView(FormView):

    def form_valid(self, form):
        user = form.save()
        returnVal = super(MyClassView, self).form_valid(form)
        send_email(user)
        return returnVal

Token verification

There are two ways to get the token verified:

  • The first one is the simplest: you just have to include the app urls in urls.py

    from django.contrib import admin
    from django.urls import path, include
    from django_email_verification import urls as email_urls  # include the urls
    
    urlpatterns = [
      path('admin/', admin.site.urls),
      ...
      path('email/', include(email_urls)),  # connect them to an arbitrary path
    ]
    

    When a request arrives to https.//mydomain.com/email/<token> the package verifies the token and:

    • if it corresponds to a pending token it renders the EMAIL_PAGE_TEMPLATE passing success=True and deletes the token
    • if it doesn't correspond it renders the EMAIL_PAGE_TEMPLATE passing success=False
  • The second one is more customizable: you can build your own view for verification, mark it as @verify_view, verify the token manually with the function verify_token(token) and execute your custom logic, here's how:

    ### For the view
    
    from django.http import HttpResponse
    from django_email_verification import verify_view, verify_token
    
    
    @verify_view
    def confirm(request, token):
        success, user = verify_token(token)
        return HttpResponse(f'Account verified, {user.username}' if success else 'Invalid token')
    
    
    ### For the urls
    from django.urls import path
    
    urlpatterns = [
        ...
        path('email/<str:token>/', confirm), # remember to set the "token" parameter in the url!
        ...
    ]
    

    IMPORTANT: the path must NOT have the name attribute set

    The library makes sure one and only one @verify_view is present and throws an error if this condition is not met.

Testing

If you are using django-email-verification and you want to test the email, if settings.DEBUG == True, then two items will be added to the email headers. You can obtain these by checking the django.core.mail outbox, which will have a non-zero length if an email has been sent. Retrieve the email and obtain the link (includes token) or the token to use in your code.

from django.core import mail

...
test
body...

try:
  email = mail.outbox[0]
  link = mail.extra_headers['LINK']
  token = mail.extra_headers['TOKEN']
  browser.visit(link)  # verifies token...
except AttributeError:
  logger.warn("no email")

For the email to be in the inbox, you will need to use the correct email backend. Use either:

EMAIL_BACKEND = 'django.core.mail.backends.locmem.EmailBackend'

or:

EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'

Console backend for development

If you want to use the console email backend provided by django, then define:

EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'

You can use all the django email backends and also your custom one.

Logo copyright:

Logo by by Filippo Veggo

"Django and the Django logo are registered trademarks of Django Software Foundation.
Usage of the Django trademarks are subject to the Django Trademark licensing Agreement."
Icons made by Kiranshastry from www.flaticon.com
Icons made by Pixel perfect from www.flaticon.com

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django-email-verification-0.3.1.tar.gz (12.7 kB view details)

Uploaded Source

Built Distribution

django_email_verification-0.3.1-py3-none-any.whl (11.0 kB view details)

Uploaded Python 3

File details

Details for the file django-email-verification-0.3.1.tar.gz.

File metadata

File hashes

Hashes for django-email-verification-0.3.1.tar.gz
Algorithm Hash digest
SHA256 1f0e32531244b165d617c0f105522e1ec2fdb48f4d7f34c496a53a4efa0b9961
MD5 d0e858d5f825e8867a5cae6f40938af2
BLAKE2b-256 15600050786d650ae8674614d6cf675171861acaa2de95c5885d4398f89679c4

See more details on using hashes here.

File details

Details for the file django_email_verification-0.3.1-py3-none-any.whl.

File metadata

File hashes

Hashes for django_email_verification-0.3.1-py3-none-any.whl
Algorithm Hash digest
SHA256 e30495a356d8ada9041317667601aef88ffe542540111197916f51477d2193f8
MD5 39072607fb27769fa6f8bcf05fe9ac0f
BLAKE2b-256 73baab21d013ab5b3038a49830a91f519a2cc4a33be38a7b4d9d7d8f6712367a

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page