Skip to main content

django-email-token-auth

Passwordless Django authentication: users log in with a one-time link (or 6-digit code) sent to their email, instead of a password. A Telegram-based login path is also included.

Features

  • Email "magic link" login — no password to remember or leak
  • 6-digit numeric code as an alternate/secondary token
  • Optional Telegram login (TelegramUser, matched by tg_user_id)
  • Automatically merges duplicate User accounts that share an email address
  • Simple per-user key/value option storage (get_option / set_option)
  • Login-attempt rate limiting
  • Django admin integration (inlines for EmailUser / TelegramUser)

Installation

  1. Install the app and its dependencies:

    pip install .
    

    (or pip install -r requirements.txt during development).

  2. Add 'emailuser' to INSTALLED_APPS.

  3. Add 'emailuser.auth.EmailAuthBackend' to AUTHENTICATION_BACKENDS.

  4. Include the app's URLs in your project, under the emailuser namespace:

    from django.urls import include, path
    
    urlpatterns = [
        path('accounts/', include(('emailuser.urls', 'emailuser'), namespace='emailuser')),
        ...
    ]
    
  5. Set the required settings:

    SITE_URL = 'https://example.com'        # used to build the emailed login link
    SERVER_EMAIL = 'support@example.com'     # From: address, and shown to users on error
    # SITE_LOGIN_URL = 'https://login.example.com'  # optional: override SITE_URL just for the link
    
  6. Run migrations:

    python manage.py migrate
    
  7. The shipped templates (user/login.html, user/auth.html) {% extends "base.html" %} and expect a {% block content %}, and are written in Russian — provide a matching base.html, or override both templates under your own templates/user/ directory.

That's it — emailuser.views.login_view, auth, and logout_view handle account creation/lookup, token generation, emailing the link, and validating it, so no view code of your own is required.

How login works

  • A visitor submits their email at {% url 'emailuser:login' %}.
  • The backend looks up (or creates) a User with that email — see "Merging duplicate accounts" below — and generates a token pair via EmailUser.generate_token():
    • auth_token: a long hash, valid for token_timelife (1 day), embedded in the emailed link ({% url 'emailuser:auth' user_id token %}).
    • int_token: a 6-digit numeric code, valid for int_token_timelife (3 minutes), for shorter-lived, manually-entered flows.
  • Visiting the link (or otherwise calling authenticate(email=user.email, token=token)) validates the token and logs the user in.

Telegram login

TelegramUser mirrors EmailUser but is keyed on tg_user_id instead of email. Create one with manual_create_telegram_user(user, tg_user), then authenticate with:

from django.contrib.auth import authenticate
user = authenticate(tg_user_id=tg_user.id, token=token)

Merging duplicate accounts

django.contrib.auth.models.User has no unique constraint on email, so it's possible for two accounts to end up sharing an address. emailuser's built-in views use emailuser.utils.get_or_merge_user(email) instead of a plain User.objects.get(email=...): if duplicates are found, every related row (from any app, via Django's own FK/O2O introspection) is reassigned to the oldest account and the duplicate(s) are deleted, so login doesn't fail with MultipleObjectsReturned.

Rate limiting

Every call to do_auth() records a LoginAttempt for that user, viewable in the Django admin. More than 11 attempts within the past hour raises TokenException instead of checking the token.

User options

Store arbitrary per-user key/value pairs:

def some_view(request):
    request.user.emailuser.set_option('some_option', 'some_value')

def another_view(request):
    value = request.user.emailuser.get_option('some_option')  # 'some_value', or False if unset

Metadata

Release files for django-email-telegram-auth 0.4.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for django-email-telegram-auth 0.4.3
File Size Uploaded
django_email_telegram_auth-0.4.3.tar.gz 11.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for django-email-telegram-auth 0.4.3
File Interpreter ABI Platform
django_email_telegram_auth-0.4.3-py3-none-any.whl Python 3 none any Details

Total release size: 30.1 kB

Release files / django_email_telegram_auth-0.4.3.tar.gz

Download URL django_email_telegram_auth-0.4.3.tar.gz
Size 11.5 kB
Tags Source
SHA-256 checksum
How to use checksums
cad102b2c77c8b6c9f4254682d94bf3d7bce8d365ec92eb818ed9277e9f8a150
BLAKE2b-256 checksum
How to use checksums
79bf695bdaca2492b6b47b4e36529c332a011c37e1353eb8302dafabde8b5904
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.4

Release files / django_email_telegram_auth-0.4.3-py3-none-any.whl

Download URL django_email_telegram_auth-0.4.3-py3-none-any.whl
Size 18.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
34d7c9faada71dbc282b4b0ab3d7b83eb8deceaa526c9d8708ec6d55c9a65b23
BLAKE2b-256 checksum
How to use checksums
df73e158ef60748f14ba32748181787fd3a3368e2a5346e07b8f009e8a7072ca
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.4

Release history Release notifications | RSS feed

This release

0.4.3 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page