This project is a secure and extensible Django authentication system built with Django Rest Framework. It includes the following features:
- Custom user model
- Login, logout, registration, and token-based authentication
- Password reset via email
- Rate-limited login and reset password endpoints using Redis
- reCAPTCHA v2 integration
- Secure password validation
- Environment variable management with
.envfile - SMTP email backend setup with Gmail (for testing)
git clone https://github.com/Abdelrahman-Hassany/secure-django-auth.git
cd secure-django-authpip install pipenv
pipenv install
pipenv shellCreate a .env file in the root directory and add the following:
SECRET_KEY=your-django-secret-key
# Google reCAPTCHA v2
RECAPTCHA_SECRET_KEY=your-recaptcha-secret-key
# Redis Cloud URL (for throttling and rate limiting)
REDIS_URL=your-redis-cloud-url
# Gmail SMTP Settings
EMAIL_HOST_USER=your-gmail-address@gmail.com
EMAIL_HOST_PASSWORD=your-app-password
# Frontend Reset Password Base URL
PASSWORD_RESET_BASE_URL=http://127.0.0.1:8000/reset_password
Note: Using Gmail for sending emails is not suitable for production. It is recommended only for local development or testing purposes. For production, use services like SendGrid, Mailgun, or Amazon SES.
python manage.py migratepython manage.py runserver- User submits their email to
/api/request-reset-password/ - If email exists, a password reset token is generated and emailed to the user
- The user follows the link to
/reset_password/{token}(frontend) - On submitting new password to
/api/reset-password/{token}/, password is updated
Redis is used to store rate limiting data. You can use Redis Cloud:
- Go to Redis Cloud
- Create a free database
- Copy the Redis URL in the format:
redis://default:<password>@<host>:<port> - Add it to
.envunderREDIS_URL
To enable reCAPTCHA v2:
- Go to Google reCAPTCHA Admin Console
- Register your site and choose reCAPTCHA v2 ("I'm not a robot" checkbox)
- Add the site key to
.envasRECAPTCHA_SECRET_KEY - In the frontend, include the reCAPTCHA script and
g-recaptcha-responsein your form submission
Example frontend snippet:
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
<form>
<!-- your fields -->
<div class="g-recaptcha" data-sitekey="your-site-key"></div>
<button type="submit">Submit</button>
</form>In the backend, verify the token with Google reCAPTCHA using requests.post to:
https://www.google.com/recaptcha/api/siteverify
- Tokens are stored in HTTP-only cookies (
access_token,refresh_token) - Middleware handles auto-refresh on expired access token
- Blacklisted tokens are cached using
django-redis - Token
jtiis used to manage blacklisting until expiration
- reCAPTCHA v2 is used in the registration process to block bots
- Login is rate-limited using
django-axesto prevent brute-force attacks - Password validation rules enforced:
- Minimum 8 characters
- Not too similar to user attributes
- Not a common password
- Not entirely numeric
- Middleware injects the token into request headers for DRF authentication
- All security best practices are followed (except
secure=Falsein dev, should beTruein production)
Note: You should include the following method in your registration serializer to activate password validation:
def validate_password(self, value):
validate_password(value)
return value- reCAPTCHA v2 is used in the registration process to block bots
- Access token refresh is seamless and secure
- Middleware injects the token into request headers for DRF authentication
After user registration, an activation code is automatically sent to the user's email. This code is required to activate the account and access protected endpoints.
- A 6-digit code is generated and sent to the registered email.
- The user must input this code on the
/activation-page/frontend view. - A dedicated endpoint
/api/active-account/accepts the code and activates the account. - Users can request a new code using the
/api/resend-code/endpoint. - Activation codes expire after 30 minutes for security.
- After registration, a 6-digit activation code is sent to the user’s email.
- User must enter this code at
/activation-page/to activate the account. - If the user is not activated, all access to protected views is blocked via middleware until activation.
- Users can request to resend the activation code via
/api/resend-code/. - Too many failed attempts (more than 5 incorrect codes within 10 minutes) are blocked via Redis-based rate limiting.
A custom JWT middleware has been implemented to block access to any part of the website unless the user has completed their activation via code.
- If a user is not activated, any attempt to access protected resources will redirect them to the
/activation-page/. - Middleware checks the
is_activatedflag on theProfilemodel and acts accordingly.
To protect against brute-force attempts when entering the activation code, a rate limit has been introduced:
- Max attempts: 5 failed tries within 10 minutes
- Backend: Redis cache is used to track attempts
- Behavior: After 5 incorrect tries, the user receives a
429 Too Many Requestsresponse for 10 minutes
This feature helps improve security during the account activation step.
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/register/ |
Register new user using reCAPTCHA |
| POST | /api/login/ |
Login with email & password |
| POST | /api/logout/ |
Logout user (invalidate token) |
| GET | /api/me/ |
Retrieve authenticated user details |
| POST | /api/request-reset-password/ |
Request password reset link |
| POST | /api/reset-password/<token>/ |
Reset password using token |
| POST | /api/active-account/ |
Activate account using a 6-digit code sent by email |
| POST | /api/resend-code/ |
Resend activation code to the user's email |
secure-django-auth/
├── Authentication/ # Custom middleware and JWT tools
├── CoreAuth/ # Views, serializers, API logic
├── templates/ # HTML frontend templates
├── static/ # Static files (CSS, JS)
├── manage.py
├── .env
└── README.md
The project includes automated API tests using Django's APITestCase.
To run the tests:
python manage.py testTests cover key authentication flows including:
- Successful and failed user registration
- Login and token issuance
- Logout and token blacklisting
- Protected routes access
- Access token refresh through middleware
Feel free to fork the repo and submit a pull request!