Skip to main content

Reusable auth + profiles foundations for Django/DRF projects

Project description

jb-drf-auth

Reusable authentication foundations for Django + Django REST Framework projects.

jb-drf-auth provides a clean, extensible base for authentication-related concerns, focused on:

  • Abstract user and profile models
  • Soft delete using django-safedelete
  • Support for multiple profiles per user
  • Project-level extensibility (different profile schemas per project)
  • Integration with DRF viewsets/serializers

This package is designed to be installed via PyPI and reused across multiple Django projects without duplicating auth logic.


✨ Features

  • ✅ Abstract User base compatible with default or custom Django users
  • ✅ Abstract Profile base (one user → many profiles)
  • ✅ Built-in soft delete via django-safedelete
  • ✅ Zero migrations inside the package (migrations live in consumer projects)
  • ✅ Dynamic model resolution via Django settings
  • ✅ Django 5 compatible
  • ✅ DRF serializers, services, and views based on base_code

📦 Installation

pip install jb-drf-auth

Add jb_drf_auth and rest_framework to INSTALLED_APPS.


⚙️ Settings

Minimal required settings (add to settings.py):

JB_DRF_AUTH_PROFILE_MODEL = "authentication.Profile"
JB_DRF_AUTH_DEVICE_MODEL = "authentication.Device"
JB_DRF_AUTH_OTP_MODEL = "authentication.OtpCode"
JB_DRF_AUTH_EMAIL_LOG_MODEL = "authentication.EmailLog"

JB_DRF_AUTH_FRONTEND_URL = "https://your-frontend"
JB_DRF_AUTH_DEFAULT_FROM_EMAIL = "no-reply@your-domain.com"

Optional:

JB_DRF_AUTH_AUTHENTICATION_TYPE = "email"  # "email", "username", "both"
JB_DRF_AUTH_AUTH_SINGLE_SESSION_ON_MOBILE = False
JB_DRF_AUTH_ADMIN_BOOTSTRAP_TOKEN = "super-secret"
JB_DRF_AUTH_PROFILE_PICTURE_UPLOAD_TO = "uploads/users/profile-pictures"
JB_DRF_AUTH_SMS_PROVIDER = "jb_drf_auth.providers.aws_sns.AwsSnsSmsProvider"
JB_DRF_AUTH_SMS_SENDER_ID = "YourBrand"
JB_DRF_AUTH_SMS_TYPE = "Transactional"
JB_DRF_AUTH_SMS_OTP_MESSAGE = "Tu codigo es {code}. Expira en {minutes} minutos." #OTP messages must use 160 GSM-7 characters only (no accents, emojis, or special symbols).
JB_DRF_AUTH_SMS_LOG_MODEL = "authentication.SmsLog"
JB_DRF_AUTH_EMAIL_PROVIDER = "jb_drf_auth.providers.django_email.DjangoEmailProvider"
JB_DRF_AUTH_EMAIL_TEMPLATES = {}
JB_DRF_AUTH_OTP_LENGTH = 6
JB_DRF_AUTH_OTP_TTL_SECONDS = 300
JB_DRF_AUTH_OTP_MAX_ATTEMPTS = 5
JB_DRF_AUTH_OTP_RESEND_COOLDOWN_SECONDS = 60
JB_DRF_AUTH_PHONE_DEFAULT_COUNTRY_CODE = "52"  # required only if clients don't send E.164 (+countrycode)

You can also configure everything using a single dict (copy/paste ready):

AUTH_USER_MODEL = "authentication.User"

JB_DRF_AUTH = {
    "PROFILE_MODEL": "authentication.Profile",
    "DEVICE_MODEL": "authentication.Device",
    "OTP_MODEL": "authentication.OtpCode",
    "SMS_LOG_MODEL": "authentication.SmsLog",
    "EMAIL_LOG_MODEL": "authentication.EmailLog",
    "FRONTEND_URL": "https://your-frontend",
    "DEFAULT_FROM_EMAIL": "no-reply@your-domain.com",
    "AUTHENTICATION_TYPE": "email",  # "email", "username", "both"
    "CLIENT_CHOICES": ("web", "mobile"),
    "AUTH_SINGLE_SESSION_ON_MOBILE": False,
    "ADMIN_BOOTSTRAP_TOKEN": "super-secret",
    "PROFILE_PICTURE_UPLOAD_TO": "uploads/users/profile-pictures",
    "PROFILE_ROLE_CHOICES": (
        ("USER", "Usuario"),
        ("COMMERCE", "Comercio"),
        ("ADMIN", "Admin"),
    ),
    "PROFILE_GENDER_CHOICES": (
        ("MALE", "Masculino"),
        ("FEMALE", "Femenino"),
        ("OTHER", "Otro"),
        ("PREFER_NOT_TO_SAY", "Prefiero no decirlo"),
    ),
    "DEFAULT_PROFILE_ROLE": "USER",
    "PROFILE_ID_CLAIM": "profile_id",
    "SMS_PROVIDER": "jb_drf_auth.providers.aws_sns.AwsSnsSmsProvider",
    "SMS_SENDER_ID": "YourBrand",
    "SMS_TYPE": "Transactional",
    "SMS_OTP_MESSAGE": "Tu codigo es {code}. Expira en {minutes} minutos.",
    "OTP_LENGTH": 6,
    "OTP_TTL_SECONDS": 300,
    "OTP_MAX_ATTEMPTS": 5,
    "OTP_RESEND_COOLDOWN_SECONDS": 60,
    "PHONE_DEFAULT_COUNTRY_CODE": "52",
    "PHONE_MIN_LENGTH": 10,
    "PHONE_MAX_LENGTH": 15,
    "EMAIL_PROVIDER": "jb_drf_auth.providers.django_email.DjangoEmailProvider",
    "EMAIL_TEMPLATES": {},
}

Email template example:

JB_DRF_AUTH_EMAIL_TEMPLATES = {
    "email_confirmation": {
        "subject": "Verifica tu correo",
        "text": "Hola {user_email}, verifica tu correo aqui: {verify_url}",
        "html": "<p>Hola {user_email},</p><a href=\"{verify_url}\">Verificar</a>",
    },
    "password_reset": {
        "subject": "Restablece tu contrasena",
        "text": "Hola {user_email}, restablece tu contrasena: {reset_url}",
        "html": "<p>Hola {user_email},</p><a href=\"{reset_url}\">Restablecer</a>",
    },
}

🧩 Models

Create concrete models in your project by extending the base classes.

# authentication/models.py
from django.db import models
from jb_drf_auth.models import (
    AbstractJbUser,
    AbstractJbProfile,
    AbstractJbDevice,
    AbstractJbEmailLog,
    AbstractJbOtpCode,
    AbstractJbSmsLog,
)


class User(AbstractJbUser):
    pass


class Profile(AbstractJbProfile):
    pass


class Device(AbstractJbDevice):
    pass


class OtpCode(AbstractJbOtpCode):
    pass


class SmsLog(AbstractJbSmsLog):
    pass


class EmailLog(AbstractJbEmailLog):
    pass

Then set AUTH_USER_MODEL = "authentication.User" and run migrations in your project.


🛣️ URLs

# project/urls.py
from django.urls import include, path

urlpatterns = [
    path("auth/", include("jb_drf_auth.urls")),
]

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

jb_drf_auth-0.1.0.tar.gz (22.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

jb_drf_auth-0.1.0-py3-none-any.whl (35.0 kB view details)

Uploaded Python 3

File details

Details for the file jb_drf_auth-0.1.0.tar.gz.

File metadata

  • Download URL: jb_drf_auth-0.1.0.tar.gz
  • Upload date:
  • Size: 22.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for jb_drf_auth-0.1.0.tar.gz
Algorithm Hash digest
SHA256 486ed1fd37dbedb902e2501246ff919b2b104b3d36de7d3bee652d0001175f1b
MD5 eb55f2cc6cc37f1713d93bbb79772cb9
BLAKE2b-256 a7965185cc940b04fc7cb5035260e86a81dc52122469bfd01cbf3a0105a4ec77

See more details on using hashes here.

Provenance

The following attestation bundles were made for jb_drf_auth-0.1.0.tar.gz:

Publisher: pypi-publish.yml on joelbarron/jb-drf-auth

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file jb_drf_auth-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: jb_drf_auth-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 35.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for jb_drf_auth-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 466f84cb3e2a42e078e776d67042fde539a79d5a7658212a7d368a9261fd74b3
MD5 cc6411d659acccf3264003c157f507b5
BLAKE2b-256 d1228a0e45352d5394b5d8c89975c85b801a838552fd49c65a9d7f3ba345312d

See more details on using hashes here.

Provenance

The following attestation bundles were made for jb_drf_auth-0.1.0-py3-none-any.whl:

Publisher: pypi-publish.yml on joelbarron/jb-drf-auth

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

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