Metadata-Version: 2.4
Name: web727token
Version: 1.1.0
Summary: Secure-by-default authentication framework for Django, Django REST Framework, and React.
Author: T.P. Thangaprabhu
License: MIT
Keywords: django,djangorestframework,drf,authentication,jwt,middleware,security,react,session,oauth,token
Classifier: Development Status :: 5 - Production/Stable
Classifier: Framework :: Django
Classifier: Framework :: Django :: 4.0
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Topic :: Internet :: WWW/HTTP :: Session
Classifier: Topic :: Security
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: <3.12,>=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: Django<4.1,>=4.0
Requires-Dist: djangorestframework<3.15,>=3.14
Requires-Dist: PyJWT<3.0,>=2.8
Provides-Extra: dev
Requires-Dist: pytest<9.0,>=7.0; extra == "dev"
Requires-Dist: pytest-django<5.0,>=4.8; extra == "dev"
Requires-Dist: coverage<8.0,>=7.0; extra == "dev"
Dynamic: license-file

# Web727Token

> **A secure-by-default authentication framework for Django, Django REST Framework, and React.**
>
> Install once. Protect every request. Keep authentication out of your application code.

```bash
pip install web727token
npm install web727token
```

---

# Why Web727Token?

Traditional authentication libraries provide JWT utilities and expect developers to wire everything together.

Web727Token takes a different approach.

It is a complete authentication framework that centralizes authentication, authorization, session management, refresh-token rotation, audit logging, device tracking, and rate limiting behind a single middleware.

Your application works with authenticated users—not authentication infrastructure.

| Traditional JWT Libraries              | Web727Token                            |
| -------------------------------------- | -------------------------------------- |
| Configure authentication on every view | Install middleware once                |
| Developers work directly with JWTs     | JWT is completely hidden               |
| Manual authentication decorators       | Middleware authenticates every request |
| Manual Axios interceptors              | Included React SDK                     |
| Refresh logic written manually         | Automatic refresh rotation             |
| Session management varies by project   | Built-in                               |
| Device tracking is custom              | Built-in                               |
| Audit logging is custom                | Built-in                               |
| Logout implementation differs          | Standardized                           |

---

# How Web727Token Compares

Authentication in the JavaScript/Python ecosystem is handled by three broad categories of tools: **raw JWT libraries**, **framework-level auth toolkits**, and **hosted identity platforms**. Web727Token sits in the second category, but is architected to remove the manual wiring that toolkits usually still require.

| Solution                         | Category                 | JWT hidden from app code | Built-in device tracking | Built-in audit logging | Self-hosted (no vendor lock-in) | Django/DRF-native | Included frontend SDK |
| --------------------------------- | ------------------------- | :-----------------------: | :------------------------: | :-----------------------: | :--------------------------------: | :------------------: | :----------------------: |
| **Web727Token**                   | Auth framework            | ✅                         | ✅                          | ✅                         | ✅                                  | ✅                    | ✅                        |
| PyJWT / `python-jose`             | Raw JWT library           | ❌                         | ❌                          | ❌                         | ✅                                  | ❌ (generic)          | ❌                        |
| djangorestframework-simplejwt     | Framework auth toolkit    | ❌                         | ❌                          | ❌                         | ✅                                  | ✅                    | ❌                        |
| Passport.js                       | Framework auth toolkit    | ❌                         | ❌                          | ❌                         | ✅                                  | ❌ (Node/Express)     | ❌                        |
| Auth.js / NextAuth.js             | Framework auth toolkit    | Partial                   | ❌                          | ❌                         | ✅                                  | ❌ (Next.js)          | ✅ (Next.js only)         |
| Firebase Authentication           | Hosted identity platform  | ✅                         | Partial                    | Partial                   | ❌                                  | ❌                    | ✅                        |
| AWS Cognito                       | Hosted identity platform  | ✅                         | Partial                    | ✅                         | ❌                                  | ❌                    | Partial (Amplify)        |
| Auth0                             | Hosted identity platform  | ✅                         | ✅                          | ✅                         | ❌                                  | ❌                    | ✅                        |
| Keycloak                          | Self-hosted IAM (OIDC/SAML) | ✅                       | Partial                    | ✅                         | ✅                                  | ❌ (protocol-based)   | ❌ (adapter required)     |

**How to read this table honestly:**

* **Raw JWT libraries** (PyJWT, SimpleJWT, Passport.js) are unopinionated toolkits, not frameworks. They are excellent building blocks and are often *more flexible* than Web727Token for teams who want to hand-roll a bespoke auth flow — but device tracking, audit logging, session invalidation, and interceptor logic all have to be built and maintained by the application team.
* **Hosted identity platforms** (Auth0, Cognito, Firebase) offer breadth Web727Token does not attempt to replace — social login federation, SAML/enterprise SSO, managed compliance certifications, and infrastructure you don't operate yourself. Their tradeoff is per-user pricing, external data residency, and a hosted dependency outside your own Django deployment.
* **Keycloak** is a mature, standards-based (OIDC/SAML) identity server and is the closest self-hosted competitor in spirit. It is protocol-first and identity-server-based rather than middleware-based, so integrating it into a Django/DRF codebase still requires an adapter layer and doesn't hide JWT handling from application code the way `request.web727` does.

Web727Token's actual differentiation is narrower and more concrete than "better than everything": it is a **self-hosted, Django/DRF-native middleware** that bundles session management, refresh rotation, device tracking, and audit logging behind one install — with a matching React SDK — so a Django team doesn't need to combine three or four separate tools (SimpleJWT + custom middleware + custom Axios interceptors + a logging package) to get that behavior.

---

# Features

### Authentication

* Middleware-driven authentication
* JWT hidden behind the framework
* Automatic authentication for every request
* Django & Django REST Framework support
* Custom Django User model support

### Security

* Access token expiration
* Refresh token rotation
* Refresh-token reuse detection
* Automatic session invalidation
* Per-user account lockout
* Per-IP rate limiting
* Device tracking
* Audit logging
* Configurable token lifetimes

### Frontend

* React SDK
* Automatic Authorization header attachment
* Silent token refresh
* Automatic retry after refresh
* Session restoration
* React authentication hook

---

# Architecture

Web727Token **does not introduce another authentication standard.**

JWT is simply an internal implementation detail.

Only **`tokens.py`** understands JWT.

Everything else—including your application code—works only with authenticated users.

```
Client
   │
   ▼
Web727 React SDK  (axios.js wrapper → Web727.client)
   │
   ▼
Authorization Header
   │
   ▼
Web727Middleware
   │
   ├── path in WEB727_PUBLIC_PATHS? ──▶ Application Code (unauthenticated)
   │
   ▼
request.web727
   │
   ▼
Application Code
```

---

# Requirements

* Python 3.9+ (<3.12)
* Django 4.0
* Django REST Framework
* React 18+ (Frontend SDK)

---

# Installation

Backend

```bash
pip install web727token
```

Frontend

```bash
npm install web727token
```

Run migrations:

```bash
python manage.py migrate web727token
```

---

# Backend Quick Start

Install the application.

```python
# settings.py

INSTALLED_APPS = [
    ...
    "web727token",
]
```

Install the middleware.

```python
MIDDLEWARE = [
    ...
    "web727token.middleware.Web727Middleware",
]
```

Enable Web727Token and configure it.

```python
WEB727_ENABLED = True
WEB727_USE_LOCAL_STORAGE = False

WEB727_PUBLIC_PATHS = [
    "/",
    "/admin/",
    "/api/token/",
    "/api/token/refresh/",
    "/api/company-logo/",
    "/api/banners/",
    "/api/pages/",
    "/api/page-details/",
    "/api/services/",
    "/api/inquiries/",
]
```

| Setting                     | Type    | Description                                                                                                   |
| ---------------------------- | ------- | --------------------------------------------------------------------------------------------------------------- |
| `WEB727_ENABLED`             | `bool`  | Master switch for the framework. When `True`, `Web727Middleware` authenticates every incoming request.          |
| `WEB727_USE_LOCAL_STORAGE`   | `bool`  | Controls where the frontend SDK persists tokens. `False` keeps token storage server-managed/cookie-based instead of browser `localStorage`. |
| `WEB727_PUBLIC_PATHS`        | `list`  | Explicit allow-list of paths the middleware treats as unauthenticated. Any request whose path matches an entry here bypasses `request.web727` authentication. All other paths require a valid session. |

> **Note:** `WEB727_PUBLIC_PATHS` performs a prefix match, so `"/admin/"` also allows nested paths such as `/admin/login/`. Keep this list as narrow as possible — every path outside it is authenticated by default.

Register framework URLs.

```python
# urls.py

urlpatterns = [
    path("web727/", include("web727token.urls")),
    path("api/", include("myapp.urls")),
]
```

That's all.

Every request under `/api/` is authenticated automatically.

No

* `authentication_classes`
* `permission_classes`
* `IsAuthenticated`

are required.

---

# Using the Authenticated User

```python
from rest_framework.views import APIView
from rest_framework.response import Response


class CustomerAPIView(APIView):

    def get(self, request):
        return Response({
            "id": request.web727.user.id,
            "username": request.web727.user.username,
        })
```

Every authenticated request automatically provides:

```python
request.web727.user
request.web727.session
request.web727.device
request.web727.roles
request.web727.permissions
request.user
```

---

# Frontend Quick Start

## 1. Initialize once, at the application entry point

Call `Web727.init()` a single time, before the app renders. This is typically done in `index.js`.

```jsx
// src/index.js

import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import { Web727 } from "web727token";

Web727.init({
    baseURL: process.env.REACT_APP_API_URL,
});

ReactDOM.createRoot(document.getElementById("root")).render(
    <App />
);
```

## 2. Create a single shared client

Instead of importing `axios` directly across the app, create one `axios.js` wrapper around `Web727.client` and import that everywhere instead. This guarantees every request in the app — from every page — automatically goes through the Web727 authentication layer (Authorization headers, silent refresh, retry-after-refresh) without any per-page setup.

```jsx
// src/axios.js

import { Web727 } from "web727token";

const axios = {
  get: (...args) => Web727.client.get(...args),
  post: (...args) => Web727.client.post(...args),
  put: (...args) => Web727.client.put(...args),
  patch: (...args) => Web727.client.patch(...args),
  delete: (...args) => Web727.client.delete(...args),
};

export default axios;
```

## 3. Use the wrapper in every page/component

Every page imports `axios` from `src/axios.js` — never the raw `axios` package. This keeps authentication completely out of application code, mirroring the backend's `request.web727` pattern.

```jsx
// src/pages/Profile.jsx

import axios from "../axios";

async function loadProfile() {
    const { data } = await axios.get("/api/profile");
    return data;
}
```

Because `Web727.init()` has already configured `baseURL` and token handling globally, no page needs to import `Web727` directly, attach headers manually, or handle refresh logic — the shared `axios.js` wrapper is the only integration point the rest of the app ever touches.

## 4. Direct SDK usage (optional)

For cases outside the request wrapper — such as login screens — you can use `Web727` directly.

```jsx
import { Web727 } from "web727token";

await Web727.login("alice", "hunter2");

const profile = await Web727.client.get("/api/profile");

await Web727.logout();
```

Or use the React hook.

```jsx
import { useWeb727Auth } from "web727token";

function LoginButton() {

    const {
        isAuthenticated,
        login,
        logout,
    } = useWeb727Auth();

    return isAuthenticated
        ? <button onClick={logout}>Logout</button>
        : <button onClick={() => login("alice", "hunter2")}>Login</button>;
}
```

The SDK automatically:

* Stores tokens
* Attaches Authorization headers
* Refreshes expired access tokens
* Retries failed requests
* Persists rotated refresh tokens

No Axios interceptor configuration is required.

---

# Built-in Framework Endpoints

These endpoints are provided by Web727Token.

| Method  | Endpoint                  | Description                                   |
| ------- | ------------------------- | --------------------------------------------- |
| POST    | `/web727/login`           | Authenticate and create a session             |
| POST    | `/web727/logout`          | Logout the current session                    |
| POST    | `/web727/refresh`         | Rotate the refresh token                      |
| GET     | `/web727/me`              | Current authenticated user                    |
| GET     | `/web727/session`         | List active sessions                          |
| GET     | `/web727/session/{id}`    | Get session details *(planned)*               |
| DELETE  | `/web727/session/{id}`    | Revoke a specific session *(planned)*         |
| DELETE  | `/web727/session`         | Logout from all devices *(planned)*           |
| PUT     | `/web727/change-password` | Change password                               |
| PATCH   | `/web727/profile`         | Update authenticated user profile *(planned)* |
| OPTIONS | `/web727/*`               | Supported automatically by Django             |
| HEAD    | `/web727/*`               | Supported automatically by Django             |

---

# Supported HTTP Methods

Web727Middleware authenticates every incoming request regardless of HTTP method.

Supported methods include:

* GET
* POST
* PUT
* PATCH
* DELETE
* OPTIONS
* HEAD

Once authenticated, `request.web727` is available for every supported request.

---

## What's Included

Web727Token provides:

- Authentication middleware
- Login, logout and token refresh endpoints
- JWT token engine
- Session management
- Device tracking
- Login history
- Audit logging
- Role and permission support
- React SDK with automatic token management
---

# Current Status

## Backend

Completed

* Middleware authentication
* JWT token engine
* Session management
* Refresh token rotation
* Refresh-token reuse detection
* Automatic session invalidation
* Login history
* Device tracking
* Audit logging
* Per-user account lockout
* Per-IP rate limiting
* Role-based authorization
* Six built-in authentication endpoints

**22 / 22 pytest-django tests passing**

Verified through automated tests and successful package builds.

---

## Frontend

Completed

* React SDK
* Login
* Logout
* Session restoration
* Automatic Authorization header
* Automatic refresh
* Automatic retry after refresh
* Refresh-token persistence
* React authentication hook
* Rollup CJS & ESM builds

**14 / 14 Vitest tests passing**

---

# Roadmap

Planned improvements include:

* Cookie-based authentication documentation
* CSRF guidance for cookie deployments
* Session management UI example
* Device management UI example
* GitHub Actions CI/CD
* PyPI publishing workflow
* npm publishing workflow

---

# Philosophy

Web727Token is **not another JWT library**.

JWT is deliberately isolated inside **`tokens.py`**.

Application developers never need to:

* Parse JWTs
* Validate JWTs
* Refresh JWTs
* Attach Authorization headers
* Configure authentication decorators
* Write Axios interceptors

Instead, developers simply work with authenticated users through `request.web727`.

---

# License

MIT License
