Skip to content

πŸ” A Django app for managing and authenticating trusted user devices using JWT. Tracks device sessions, enforces device-based login validation, and lets users manage their logged-in devices securely.

License

Notifications You must be signed in to change notification settings

ganiyevuz/django-trusted-devices

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

5 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ” Django Trusted Device

A plug-and-play Django app that adds trusted device management to your API authentication system using djangorestframework-simplejwt. Automatically associates tokens with user devices, tracks login locations, and enables per-device control over access and session management.


Docs

πŸš€ Features

  • πŸ”‘ JWT tokens include a unique device_uid
  • 🌍 Auto-detect IP, region, and city via ipapi.co
  • πŸ›‘οΈ Per-device session tracking with update/delete restrictions
  • πŸ”„ Custom TokenObtainPair, TokenRefresh, and TokenVerify views
  • πŸšͺ Logout unwanted sessions from the device list
  • 🧼 Automatic cleanup, optional global control rules
  • 🧩 API-ready – supports DRF out of the box
  • βš™οΈ Fully customizable via TRUSTED_DEVICE Django settings
  • 🚫 Rejects refresh/verify from unknown or expired devices

πŸ“¦ Installation

pip install django-trusted-device

Add to your INSTALLED_APPS:

INSTALLED_APPS = [
    ...
    'trusted_devices',
    'rest_framework_simplejwt.token_blacklist',
]

Run migrations:

python manage.py migrate

βš™οΈ Configuration

Customize behavior in settings.py:

TRUSTED_DEVICE = {
    "DELETE_DELAY_MINUTES": 60 * 24 * 7,  # 7 days
    "UPDATE_DELAY_MINUTES": 60,           # 1 hour
    "ALLOW_GLOBAL_DELETE": True,
    "ALLOW_GLOBAL_UPDATE": True,
}

🧩 Usage

πŸ” SimpleJWT configuration

Replace default SimpleJWT serializers with TrustedDevice serializers.:

from datetime import timedelta

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'trusted_devices.authentication.TrustedDeviceAuthentication',
    ),
}

SIMPLE_JWT = {
    "ACCESS_TOKEN_LIFETIME": timedelta(minutes=60),
    "REFRESH_TOKEN_LIFETIME": timedelta(days=30),
    "AUTH_HEADER_TYPES": ("Bearer",),
    "TOKEN_OBTAIN_SERIALIZER": 'trusted_devices.serializers.TrustedDeviceTokenObtainPairSerializer',
    "TOKEN_REFRESH_SERIALIZER": 'trusted_devices.serializers.TrustedDeviceTokenRefreshSerializer',
    "TOKEN_VERIFY_SERIALIZER": 'trusted_devices.serializers.TrustedDeviceTokenVerifySerializer',
}

πŸ” Custom Token Views

Replace the default SimpleJWT views with:

from trusted_devices.views import (
    TrustedDeviceTokenObtainPairView,
    TrustedDeviceTokenRefreshView,
    TrustedDeviceTokenVerifyView,
)

urlpatterns = [
    path('api/token/', TrustedDeviceTokenObtainPairView.as_view(), name='token_obtain_pair'),
    path('api/token/refresh/', TrustedDeviceTokenRefreshView.as_view(), name='token_refresh'),
    path('api/token/verify/', TrustedDeviceTokenVerifyView.as_view(), name='token_verify'),
]

πŸ“‘ Device Management API

Use the provided TrustedDeviceViewSet:

from trusted_devices.views import TrustedDeviceViewSet

router.register(r'trusted-devices', TrustedDeviceViewSet, basename='trusted-device')

Endpoints:

  • GET /trusted-devices β€” List all trusted devices
  • DELETE /trusted-devices/{device_uid} β€” Delete a device
  • PATCH /trusted-devices/{device_uid} β€” Update device permissions

πŸ‘€ Device Model

Each trusted device includes:

  • device_uid: Unique UUID
  • user_agent: Browser or device string
  • ip_address: IP address
  • country, region, city: Geolocation (via ipapi.co)
  • last_seen, created_at: Timestamps
  • can_delete_other_devices, can_update_other_devices: Optional privileges

🧠 How It Works

  1. During login, a device_uid is generated and embedded in the token.
  2. Clients use that token (with device_uid) for refresh/verify.
  3. Each request is linked to a known device.
  4. Users can manage or restrict their devices via API or Admin.

πŸ§ͺ Testing Locally

# 🧩 Create and activate a uv-managed virtual environment
uv venv
source .venv/bin/activate  # Windows: .venv\Scripts\activate

# πŸ“¦ Install the package in editable mode with dev extras
uv pip install -e ".[dev]"

# πŸ§ͺ Run the test suite
pytest

🧱 Dependencies

  • Django
  • Django REST Framework
  • djangorestframework-simplejwt
  • ipapi.co (for IP geolocation)

πŸ—ƒοΈ Model Snapshot

Field Purpose
device_uid UUID primary key
user_agent, ip_address Device fingerprint
country / region / city Geo‑lookup
last_seen / created_at Activity timestamps
can_update_other_devices Granular permission
can_delete_other_devices Granular permission

🀝 Collaboration & Contributing

We love community contributions! To collaborate:

  1. Fork the repo and create a feature branch:

    git checkout -b feature/my-amazing-idea
  2. Follow code style – run:

    make lint  # runs flake8, isort, black
  3. Write & run tests:

    pytest
  4. Commit with clear messages and open a Pull Request. GitHub Actions will lint + test your branch automatically.


πŸ—£οΈ Discussions & Issues


πŸ›  Maintainer Workflow

  • PRs require at least one approval and passing CI
  • We squash‑merge to keep history clean
  • Follows Semantic Versioning (MAJOR.MINOR.PATCH), tagged as vX.Y.Z

πŸ“„ License

MIT


Made with ❀️ by Jahongir Ganiev Security questions or commercial support? Open an issue or email [email protected]

About

πŸ” A Django app for managing and authenticating trusted user devices using JWT. Tracks device sessions, enforces device-based login validation, and lets users manage their logged-in devices securely.

Resources

License

Stars

Watchers

Forks

Packages

No packages published