---
````markdown
# Django Auth Boilerplate ๐
A simple, production-ready Django authentication boilerplate using **JWT (JSON Web Tokens)** powered by `djangorestframework-simplejwt`.
## Features
โ
JWT Authentication (access & refresh tokens)
โ
Registration with validation
โ
Login & Logout
โ
Token Blacklisting
โ
Custom Exception Handling with Logging
โ
Throttling (Rate Limiting)
โ
Clean project structure
โ
Ready for PyPI packaging
---
## ๐ฆ Installation
```bash
pip install auth-boilerplate
````
Or if youโre developing locally:
```bash
git clone https://github.com/Meekemma/auth-boilerplate.git
cd auth-boilerplate
pip install -r requirements.txt
```
---
## โ๏ธ Setup Instructions
1. **Add to `INSTALLED_APPS`** in your `settings.py`:
```python
INSTALLED_APPS = [
...
'rest_framework',
'rest_framework_simplejwt.token_blacklist',
'your_auth_app', # Replace with your app name
]
```
2. **Configure Authentication & Throttling:**
```python
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_simplejwt.authentication.JWTAuthentication',
),
'DEFAULT_THROTTLE_CLASSES': [
'rest_framework.throttling.ScopedRateThrottle',
],
'DEFAULT_THROTTLE_RATES': {
'login': '3/minute',
'register': '5/minute',
'logout': '5/minute',
},
'EXCEPTION_HANDLER': 'coreuser.utils.custom_exception_handler',
}
```
3. **Add JWT Settings (Optional):**
```python
from datetime import timedelta
SIMPLE_JWT = {
'ACCESS_TOKEN_LIFETIME': timedelta(minutes=5),
'REFRESH_TOKEN_LIFETIME': timedelta(days=1),
'BLACKLIST_AFTER_ROTATION': True,
}
```
---
## ๐ Generating a Secret Key
Run this in Python shell:
```python
from django.core.management.utils import get_random_secret_key
print(get_random_secret_key())
```
Copy the result and paste it into your `.env` or `settings.py` as:
```python
SECRET_KEY = 'your-generated-secret-key'
```
---
## ๐ฎ API Endpoints
| Method | Endpoint | Description |
| ------ | ----------------- | ------------------------ |
| POST | `/register/` | Register a user |
| POST | `/login/` | Obtain tokens (JWT) |
| POST | `/logout/` | Logout & blacklist token |
| POST | `/token/refresh/` | Refresh access token |
---
## ๐งช Testing with Postman
### โ
**Registration**
```json
{
"first_name": "John",
"last_name": "Doe",
"email": "john@example.com",
"password": "StrongPassword123!",
"password2": "StrongPassword123!"
}
```
### ๐ **Login**
```json
{
"email": "john@example.com",
"password": "StrongPassword123!"
}
```
**Response:**
```json
{
"refresh": "your-refresh-token",
"access": "your-access-token",
"user": {
"id": 1,
"email": "john@example.com",
"first_name": "John",
"last_name": "Doe"
}
}
```
---
### ๐ช **Logout**
```json
{
"refresh": "your-refresh-token"
}
```
**Note:** This will blacklist the token and invalidate future use.
---
### ๐ **Token Refresh**
```json
{
"refresh": "your-refresh-token"
}
```
**Response:**
```json
{
"access": "new-access-token"
}
```
---
---
## ๐ก Contribution
Pull requests are welcome! Please fork the repo and submit a PR with a clear description.
---
## ๐ License
This project is licensed under the MIT License.
---
## ๐ซ Contact
* Author: [@meekemma](https://github.com/meekemma)
* Email: [ibehemmanuel32@gmail.com](mailto:ibehemmanuel32@gmail.com)
```
---
```
Raw data
{
"_id": null,
"home_page": "https://github.com/Meekemma/auth-boilerplate.git",
"name": "django-auth-boilerplate",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": null,
"keywords": "django authentication jwt rest framework boilerplate",
"author": "Emmanuel Ibe",
"author_email": "ibehemmanuel32@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/00/55/1746cf680c65812eec526b2f9d2912c363cbfd5f4a5f9420a6a6f1f50d00/django_auth_boilerplate-0.1.0.tar.gz",
"platform": null,
"description": "\r\n---\r\n\r\n````markdown\r\n# Django Auth Boilerplate \ud83d\udd10\r\n\r\nA simple, production-ready Django authentication boilerplate using **JWT (JSON Web Tokens)** powered by `djangorestframework-simplejwt`.\r\n\r\n## Features\r\n\r\n\u2705 JWT Authentication (access & refresh tokens) \r\n\u2705 Registration with validation \r\n\u2705 Login & Logout \r\n\u2705 Token Blacklisting \r\n\u2705 Custom Exception Handling with Logging \r\n\u2705 Throttling (Rate Limiting) \r\n\u2705 Clean project structure \r\n\u2705 Ready for PyPI packaging\r\n\r\n\r\n---\r\n\r\n## \ud83d\udce6 Installation\r\n\r\n```bash\r\npip install auth-boilerplate\r\n````\r\n\r\nOr if you\u2019re developing locally:\r\n\r\n```bash\r\ngit clone https://github.com/Meekemma/auth-boilerplate.git\r\ncd auth-boilerplate\r\npip install -r requirements.txt\r\n```\r\n\r\n---\r\n\r\n## \u2699\ufe0f Setup Instructions\r\n\r\n1. **Add to `INSTALLED_APPS`** in your `settings.py`:\r\n\r\n```python\r\nINSTALLED_APPS = [\r\n ...\r\n 'rest_framework',\r\n 'rest_framework_simplejwt.token_blacklist',\r\n 'your_auth_app', # Replace with your app name\r\n]\r\n```\r\n\r\n2. **Configure Authentication & Throttling:**\r\n\r\n```python\r\nREST_FRAMEWORK = {\r\n 'DEFAULT_AUTHENTICATION_CLASSES': (\r\n 'rest_framework_simplejwt.authentication.JWTAuthentication',\r\n ),\r\n 'DEFAULT_THROTTLE_CLASSES': [\r\n 'rest_framework.throttling.ScopedRateThrottle',\r\n ],\r\n 'DEFAULT_THROTTLE_RATES': {\r\n 'login': '3/minute',\r\n 'register': '5/minute',\r\n 'logout': '5/minute',\r\n },\r\n 'EXCEPTION_HANDLER': 'coreuser.utils.custom_exception_handler',\r\n}\r\n```\r\n\r\n3. **Add JWT Settings (Optional):**\r\n\r\n```python\r\nfrom datetime import timedelta\r\n\r\nSIMPLE_JWT = {\r\n 'ACCESS_TOKEN_LIFETIME': timedelta(minutes=5),\r\n 'REFRESH_TOKEN_LIFETIME': timedelta(days=1),\r\n 'BLACKLIST_AFTER_ROTATION': True,\r\n}\r\n```\r\n\r\n---\r\n\r\n## \ud83d\udd11 Generating a Secret Key\r\n\r\nRun this in Python shell:\r\n\r\n```python\r\nfrom django.core.management.utils import get_random_secret_key\r\nprint(get_random_secret_key())\r\n```\r\n\r\nCopy the result and paste it into your `.env` or `settings.py` as:\r\n\r\n```python\r\nSECRET_KEY = 'your-generated-secret-key'\r\n```\r\n---\r\n\r\n\r\n\r\n## \ud83d\udcee API Endpoints\r\n\r\n| Method | Endpoint | Description |\r\n| ------ | ----------------- | ------------------------ |\r\n| POST | `/register/` | Register a user |\r\n| POST | `/login/` | Obtain tokens (JWT) |\r\n| POST | `/logout/` | Logout & blacklist token |\r\n| POST | `/token/refresh/` | Refresh access token |\r\n\r\n---\r\n\r\n## \ud83e\uddea Testing with Postman\r\n\r\n### \u2705 **Registration**\r\n\r\n```json\r\n{\r\n \"first_name\": \"John\",\r\n \"last_name\": \"Doe\",\r\n \"email\": \"john@example.com\",\r\n \"password\": \"StrongPassword123!\",\r\n \"password2\": \"StrongPassword123!\"\r\n}\r\n```\r\n\r\n### \ud83d\udd10 **Login**\r\n\r\n```json\r\n{\r\n \"email\": \"john@example.com\",\r\n \"password\": \"StrongPassword123!\"\r\n}\r\n```\r\n\r\n**Response:**\r\n\r\n```json\r\n{\r\n \"refresh\": \"your-refresh-token\",\r\n \"access\": \"your-access-token\",\r\n \"user\": {\r\n \"id\": 1,\r\n \"email\": \"john@example.com\",\r\n \"first_name\": \"John\",\r\n \"last_name\": \"Doe\"\r\n }\r\n}\r\n```\r\n\r\n---\r\n\r\n### \ud83d\udeaa **Logout**\r\n\r\n```json\r\n{\r\n \"refresh\": \"your-refresh-token\"\r\n}\r\n```\r\n\r\n**Note:** This will blacklist the token and invalidate future use.\r\n\r\n---\r\n\r\n### \ud83d\udd04 **Token Refresh**\r\n\r\n```json\r\n{\r\n \"refresh\": \"your-refresh-token\"\r\n}\r\n```\r\n\r\n**Response:**\r\n\r\n```json\r\n{\r\n \"access\": \"new-access-token\"\r\n}\r\n```\r\n\r\n---\r\n\r\n---\r\n\r\n## \ud83d\udca1 Contribution\r\n\r\nPull requests are welcome! Please fork the repo and submit a PR with a clear description.\r\n\r\n---\r\n\r\n## \ud83d\udcdd License\r\n\r\nThis project is licensed under the MIT License.\r\n\r\n---\r\n\r\n## \ud83d\udceb Contact\r\n\r\n* Author: [@meekemma](https://github.com/meekemma)\r\n* Email: [ibehemmanuel32@gmail.com](mailto:ibehemmanuel32@gmail.com)\r\n\r\n```\r\n\r\n---\r\n\r\n```\r\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "A clean Django authentication boilerplate with JWT, rate limiting, and custom exception handling.",
"version": "0.1.0",
"project_urls": {
"Bug Tracker": "https://github.com/Meekemma/auth-boilerplate.git/issues",
"Documentation": "https://github.com/Meekemma/auth-boilerplate.git#readme",
"Homepage": "https://github.com/Meekemma/auth-boilerplate.git"
},
"split_keywords": [
"django",
"authentication",
"jwt",
"rest",
"framework",
"boilerplate"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "2e14ed8c097ba2be9e4000075135602a8ac63cdedbf1becdaef0c04c9dd8483b",
"md5": "1c9601439dba386ad9dd665d19419cd3",
"sha256": "b3eda69cb8f535bec711017d88009b0bcee5c5ec3ccb039446d6d5903e49770b"
},
"downloads": -1,
"filename": "django_auth_boilerplate-0.1.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "1c9601439dba386ad9dd665d19419cd3",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8",
"size": 15286,
"upload_time": "2025-07-28T22:30:55",
"upload_time_iso_8601": "2025-07-28T22:30:55.508544Z",
"url": "https://files.pythonhosted.org/packages/2e/14/ed8c097ba2be9e4000075135602a8ac63cdedbf1becdaef0c04c9dd8483b/django_auth_boilerplate-0.1.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "00551746cf680c65812eec526b2f9d2912c363cbfd5f4a5f9420a6a6f1f50d00",
"md5": "8336f5f608000a45bca0bd8fc16a00d1",
"sha256": "c06f9783e786ec653b0d257efd62b6b36e739b20f47b2b5d44f7efa51c5bf9bd"
},
"downloads": -1,
"filename": "django_auth_boilerplate-0.1.0.tar.gz",
"has_sig": false,
"md5_digest": "8336f5f608000a45bca0bd8fc16a00d1",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 12349,
"upload_time": "2025-07-28T22:30:57",
"upload_time_iso_8601": "2025-07-28T22:30:57.090087Z",
"url": "https://files.pythonhosted.org/packages/00/55/1746cf680c65812eec526b2f9d2912c363cbfd5f4a5f9420a6a6f1f50d00/django_auth_boilerplate-0.1.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-07-28 22:30:57",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "Meekemma",
"github_project": "auth-boilerplate",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"requirements": [
{
"name": "asgiref",
"specs": [
[
"==",
"3.9.1"
]
]
},
{
"name": "certifi",
"specs": [
[
"==",
"2025.7.14"
]
]
},
{
"name": "charset-normalizer",
"specs": [
[
"==",
"3.4.2"
]
]
},
{
"name": "Django",
"specs": [
[
"==",
"5.2.4"
]
]
},
{
"name": "djangorestframework",
"specs": [
[
"==",
"3.16.0"
]
]
},
{
"name": "djangorestframework_simplejwt",
"specs": [
[
"==",
"5.5.1"
]
]
},
{
"name": "docutils",
"specs": [
[
"==",
"0.21.2"
]
]
},
{
"name": "id",
"specs": [
[
"==",
"1.5.0"
]
]
},
{
"name": "idna",
"specs": [
[
"==",
"3.10"
]
]
},
{
"name": "jaraco.classes",
"specs": [
[
"==",
"3.4.0"
]
]
},
{
"name": "jaraco.context",
"specs": [
[
"==",
"6.0.1"
]
]
},
{
"name": "jaraco.functools",
"specs": [
[
"==",
"4.2.1"
]
]
},
{
"name": "keyring",
"specs": [
[
"==",
"25.6.0"
]
]
},
{
"name": "markdown-it-py",
"specs": [
[
"==",
"3.0.0"
]
]
},
{
"name": "mdurl",
"specs": [
[
"==",
"0.1.2"
]
]
},
{
"name": "more-itertools",
"specs": [
[
"==",
"10.7.0"
]
]
},
{
"name": "nh3",
"specs": [
[
"==",
"0.3.0"
]
]
},
{
"name": "packaging",
"specs": [
[
"==",
"25.0"
]
]
},
{
"name": "Pygments",
"specs": [
[
"==",
"2.19.2"
]
]
},
{
"name": "PyJWT",
"specs": [
[
"==",
"2.10.1"
]
]
},
{
"name": "python-dotenv",
"specs": [
[
"==",
"1.1.1"
]
]
},
{
"name": "pywin32-ctypes",
"specs": [
[
"==",
"0.2.3"
]
]
},
{
"name": "readme_renderer",
"specs": [
[
"==",
"44.0"
]
]
},
{
"name": "requests",
"specs": [
[
"==",
"2.32.4"
]
]
},
{
"name": "requests-toolbelt",
"specs": [
[
"==",
"1.0.0"
]
]
},
{
"name": "rfc3986",
"specs": [
[
"==",
"2.0.0"
]
]
},
{
"name": "rich",
"specs": [
[
"==",
"14.1.0"
]
]
},
{
"name": "setuptools",
"specs": [
[
"==",
"80.9.0"
]
]
},
{
"name": "sqlparse",
"specs": [
[
"==",
"0.5.3"
]
]
},
{
"name": "twine",
"specs": [
[
"==",
"6.1.0"
]
]
},
{
"name": "tzdata",
"specs": [
[
"==",
"2025.2"
]
]
},
{
"name": "urllib3",
"specs": [
[
"==",
"2.5.0"
]
]
},
{
"name": "wheel",
"specs": [
[
"==",
"0.45.1"
]
]
}
],
"lcname": "django-auth-boilerplate"
}