Introduction
Ever wondered how to build a robust user authentication system without spending weeks writing boilerplate code? In this comprehensive guide, I’ll show you exactly how I used GitHub Copilot Chat to create a complete user management system for a Django application – complete with JWT authentication, OTP verification, referral systems, and more.
By the end of this tutorial, you’ll have built:
✅ Custom User model with roles and verification
✅ JWT-based authentication with token blacklisting
✅ Email-based OTP verification system
✅ Password reset functionality
✅ Referral code system
✅ Comprehensive API endpoints
✅ Admin interface integration
✅ Complete test suite
What makes this special? We’re not just copy-pasting code – we’re learning how to collaborate effectively with AI to build production-grade software.
🚀 Prerequisites & Setup
Before we start, make sure you have:
Python 3.8+ and Django 5.0+
GitHub Copilot subscription
VS Code with GitHub Copilot extension
Basic understanding of Django and REST APIs
Project Structure We’ll Build:
wasteworth-backend/
├── config/
│ ├── settings.py
│ └── urls.py
├── apps/
│ └── users/
│ ├── models.py
│ ├── views.py
│ ├── serializers.py
│ ├── urls.py
│ └── admin.py
└── requirements.txt
Step 1: Setting Up the Foundation
🎯 Goal: Create the basic Django project structure and configure Copilot Chat for optimal assistance.
Copilot Chat Settings:
Context: Keep your workspace files open
Model: GPT-4 (for complex architectural decisions)
Conversation Mode: Extended chat for iterative development
First Prompt:
`I’m building a Django REST API for a waste management platform called “WasteWorth”. I need to create a complete user authentication system with the following features:
- Custom User model with email as username
- JWT authentication
- OTP verification for signup/login/password reset
- User roles (disposer, recycler, admin)
- Referral system
- Location tracking (lat/lng)
- Wallet balance integration
Please help me start by creating the basic project structure and requirements.txt file.`
Expected Response: Copilot will suggest a project structure and requirements.txt with necessary packages.
Testing This Step:
`# Create virtual environment
python -m venv env
source env/bin/activate # On Windows: env\Scripts\activate
pip install -r requirements.txt
python manage.py check`
Step 2: Building the Custom User Model
🎯 Goal: Create a robust User model that serves as the foundation for our authentication system.
Prompt:
`Now I need to create a custom User model in apps/users/models.py with these specifications:
- UUID primary key instead of integer
- Email as USERNAME_FIELD (no username field)
- Fields: name, email, phone, role, is_verified, location_lat, location_lng, address_location, wallet_balance, referral_code, referred_by
- Role choices: disposer, recycler, admin (default: disposer)
- Auto-generate unique referral codes
- Include proper timestamps
- Custom UserManager for email-based authentication
Also create an OTP model for verification with purpose field (signup, login, reset) and expiration logic.`
Key Copilot Features Used:
Context awareness: References Django best practices
Code generation: Creates complete model with relationships
Validation logic: Adds proper field constraints
Testing This Step:
`# Create and run migrations
python manage.py makemigrations
python manage.py migrate
python manage.py shell
# Test user creation
from apps.users.models import User
user = User.objects.create_user(
email=”test@example.com“,
password=’testpass123′,
name=”Test User”
)
print(f”User created: {user.email}, Referral: {user.referral_code}”)`
Step 3: Creating Serializers
🎯 Goal: Build comprehensive serializers for all user operations with proper validation.
Prompt:
`Create serializers in apps/users/serializers.py for:
- UserSignupSerializer – handles registration with password confirmation, referral code validation
- UserLoginSerializer – supports login with email or phone
- OTPVerifySerializer – verifies OTP for different purposes (signup, login, reset)
- UserProfileSerializer – returns user data in camelCase for frontend consumption
Include proper validation methods and error handling. The API should follow REST conventions with descriptive error messages.`
Advanced Copilot Technique:
Ask for specific validation requirements:
Follow-up Prompt:
`Add custom validation to the serializers:
- Email uniqueness check in signup
- Referral code validation (must exist in database)
- Password strength requirements (min 8 characters)
- Phone number format validation
- Proper camelCase field mapping for frontend compatibility`
Testing This Step:
`# Test in Django shell
from apps.users.serializers import UserSignupSerializer
data = {
‘name’: ‘John Doe’,
’email’: ‘john@example.com‘,
‘password’: ‘securepass123’,
‘confirmPassword’: ‘securepass123’,
‘phone’: ‘+1234567890’
}
serializer = UserSignupSerializer(data=data)
if serializer.is_valid():
user = serializer.save()
print(“User created successfully!”)
else:
print(“Validation errors:”, serializer.errors)`
Step 4: Implementing Views & Authentication Logic
🎯 Goal: Create secure, well-documented API endpoints with proper error handling.
Main Prompt:
`Create views in apps/users/views.py with these API endpoints:
- POST /signup/ – User registration with immediate OTP sending
- POST /login/ – Credential verification + OTP sending
- POST /VerifyOTP/?action=signup|login|reset – OTP verification with JWT token return
- POST /request-password-reset/ – Password reset initiation
- POST /logout/ – JWT token blacklisting
Requirements:
- Use function-based views with proper decorators
- Implement OTP generation and email sending utility
- Return JWT tokens only after OTP verification
- Handle all error cases with descriptive messages
- Include proper status codes
Enhance the authentication security:
Security-Focused Follow-up:
- Hash OTP codes before storing in database
- Implement OTP expiration (10 minutes)
- Prevent OTP reuse
- Rate limiting considerations
- Proper token blacklisting on logout
- User enumeration protection in password reset`
Testing This Step:
Create a simple test script:
`# test_auth.py
import requests
import json
BASE_URL = ‘http://localhost:8000/api/v1/users‘
signup_data = {
‘name’: ‘Test User’,
’email’: ‘test@example.com‘,
‘password’: ‘testpass123’,
‘confirmPassword’: ‘testpass123’,
‘phone’: ‘+1234567890’
}
response = requests.post(f'{BASE_URL}/signup/’, json=signup_data)
print(“Signup Response:”, response.status_code, response.json())
otp_data = {
’emailOrPhone’: ‘test@example.com‘,
‘otp’: ‘123456’ # Replace with actual OTP from email
}
response = requests.post(f'{BASE_URL}/VerifyOTP/?action=signup’, json=otp_data)
print(“OTP Verification:”, response.status_code, response.json())`
Step 5: Email Integration & OTP System
🎯 Goal: Set up reliable email sending for OTP delivery.
Prompt
`Create a robust OTP system in apps/users/utils.py with:
-
generate_and_send_otp function that:
- Generates 6-digit numeric OTP
- Hashes OTP before database storage
- Sends formatted email with OTP
- Handles email sending failures gracefully
- Sets proper expiration time (10 minutes)
-
Email configuration in settings.py for both development (console backend) and production (SMTP)
-
Professional email templates with company branding
Make it production-ready with proper error handling and logging.`
Environment Configuration Prompt:
`Help me set up environment variables for email configuration:
- Create .env.example with all email settings
- Configure settings.py to read email settings from environment
- Set up both development (console) and production (SMTP) email backends
- Include proper email security settings (TLS, SSL)`
Testing Email System:# Test email in development
python manage.py shell
`from apps.users.utils import generate_and_send_otp
from apps.users.models import User
user = User.objects.get(email=”test@example.com“)
otp = generate_and_send_otp(user, ‘login’)
print(f”OTP sent: {otp.purpose}”)
Step 6: URL Configuration & API Documentation
🎯 Goal: Create clean, RESTful URL patterns and comprehensive API documentation.
Prompt:
`Create URL configuration in apps/users/urls.py with clean, RESTful patterns:
- /api/v1/users/signup/ – POST
- /api/v1/users/login/ – POST
- /api/v1/users/logout/ – POST (authenticated)
- /api/v1/users/request-password-reset/ – POST
- /api/v1/users/VerifyOTP/ – POST (with query parameter for action)
Also update the main config/urls.py to include the users app URLs.
Provide API documentation in Markdown format with:
- Request/response examples
- Error codes and messages
- Authentication requirements
- Rate limiting information`
API Documentation Prompt:
`Generate comprehensive API documentation for the user authentication endpoints including:
- Authentication flow diagrams
- Request/response schemas in JSON format
- Error handling examples
- cURL command examples for testing
- Postman collection structure`
Testing URL Configuration:# Test URL resolution
python manage.py shell
from django.urls import reverse
print("Signup URL:", reverse('users:signup'))
print("Login URL:", reverse('users:login'))
print("Logout URL:", reverse('users:logout'))
Step 7: Admin Interface Integration
🎯 Goal: Create a professional Django admin interface for user management.
Prompt:
`Create a comprehensive Django admin configuration in apps/users/admin.py:
-
UserAdmin with:
- Custom list display showing email, name, role, verification status, wallet balance
- Filters for role, verification status, date joined
- Search functionality for email, name, phone, referral code
- Fieldsets organized logically (Personal Info, Location, Wallet & Referrals, Permissions)
- Color-coded verification status display
- Read-only fields for timestamps and computed values
-
OTPAdmin with:
- List display showing user, purpose, status, expiration
- Read-only fields (OTPs shouldn’t be editable)
- Color-coded expiration status
- Proper filtering and search
Make it production-ready with proper security considerations.`
Testing Admin Interface:
`# Create superuser
python manage.py createsuperuser
python manage.py runserver
Step 8: Comprehensive Test Suite
🎯 Goal: Build a complete test suite ensuring reliability and catching regressions.
Main Testing Prompt
{% raw %}`Create comprehensive tests in apps/users/tests.py covering:
-
UserSignupTestCase:
- Valid signup with all fields
- Password mismatch validation
- Duplicate email handling
- Invalid email format
- Missing required fields
- Password strength validation
-
UserLoginTestCase:
- Valid login credentials
- Invalid email/password
- Missing fields validation
-
OTPVerificationTestCase:
- Valid OTP verification for different actions
- Expired OTP handling
- Invalid OTP codes
- Used OTP prevention
-
UserLogoutTestCase:
- Valid logout with refresh token
- Invalid token handling
- Unauthenticated access
Use Django’s TestCase and APITestCase for proper database isolation.`
Advanced Testing Prompt:
`Add integration tests and edge cases:
- Email sending functionality tests
- Referral code generation and validation
- User role permissions
- Concurrent OTP generation handling
- Rate limiting simulation
- Token expiration scenarios
- Database constraint validation
Include test utilities for:
- User factory creation
- OTP mocking
- Email backend testing
- JWT token generation helpers`
Running Tests:
`# Run all tests
python manage.py test
python manage.py test apps.users.tests.UserSignupTestCase
pip install coverage
coverage run –source=”.” manage.py test
coverage report`
Step 9: Security Hardening & Production Optimization
🎯 Goal: Ensure the authentication system is production-ready and secure.
Security Audit Prompt:
`Review and enhance the security of our user authentication system:
-
JWT token security:
- Proper token expiration times
- Secure token storage recommendations
- Refresh token rotation
- Token blacklisting efficiency
-
OTP security:
- Rate limiting OTP generation
- Brute force protection
- OTP entropy analysis
- Prevention of timing attacks
-
User data protection:
- Password hashing verification
- Sensitive data in logs
- API response sanitization
- Database query optimization
-
General security:
- Input validation completeness
- Error message information leakage
- CORS configuration
- Rate limiting implementation
Provide specific code improvements and Django settings recommendations.`
`Review and enhance the security of our user authentication system:
-
JWT token security:
- Proper token expiration times
- Secure token storage recommendations
- Refresh token rotation
- Token blacklisting efficiency
-
OTP security:
- Rate limiting OTP generation
- Brute force protection
- OTP entropy analysis
- Prevention of timing attacks
-
User data protection:
- Password hashing verification
- Sensitive data in logs
- API response sanitization
- Database query optimization
-
General security:
- Input validation completeness
- Error message information leakage
- CORS configuration
- Rate limiting implementation
Provide specific code improvements and Django settings recommendations.`
Performance Optimization Prompt:
`Optimize the authentication system for production:
-
Database optimizations:
- Query optimization with select_related/prefetch_related
- Database indexes for frequently queried fields
- OTP cleanup strategy for expired records
-
Caching strategies:
- User session caching
- OTP rate limiting with Redis
- API response caching where appropriate
-
Email system optimization:
- Async email sending with Celery
- Email template optimization
- SMTP connection pooling
Provide implementation examples and configuration recommendations.`
Step 10: Documentation & Deployment
🎯 Goal: Create comprehensive documentation and deployment guides.
Documentation Prompt:
`Create comprehensive documentation for the user authentication system:
-
README.md with:
- Project overview and features
- Installation and setup instructions
- Environment variable configuration
- API endpoint documentation
- Testing instructions
-
API_DOCUMENTATION.md with:
- Authentication flow diagrams
- Detailed endpoint specifications
- Request/response examples
- Error code references
- Integration examples
-
DEPLOYMENT.md with:
- Production deployment checklist
- Environment setup
- Security considerations
- Monitoring and logging setup
-
CONTRIBUTING.md with:
- Development workflow
- Testing requirements
- Code style guidelines
- Pull request process`
🧪 Final Testing & Quality Assurance
Complete Integration Test Script:
Create this comprehensive test to verify everything works:
`# integration_test.py
import requests
import time
def test_complete_auth_flow():
“””Test the complete authentication flow”””
BASE_URL = ‘http://localhost:8000/api/v1/users‘
# 1. Signup
print("Testing signup...")
signup_data = {
'name': 'Integration Test User',
'email': 'integration@test.com',
'password': 'testpass123',
'confirmPassword': 'testpass123',
'phone': '+1234567890'
}
response = requests.post(f'{BASE_URL}/signup/', json=signup_data)
assert response.status_code == 201
print("✅ Signup successful")
# 2. Login (should send OTP)
print("Testing login...")
login_data = {
'emailOrPhone': 'integration@test.com',
'password': 'testpass123'
}
response = requests.post(f'{BASE_URL}/login/', json=login_data)
assert response.status_code == 200
print("✅ Login credentials verified, OTP sent")
# 3. Password Reset Request
print("Testing password reset...")
reset_data = {'emailOrPhone': 'integration@test.com'}
response = requests.post(f'{BASE_URL}/request-password-reset/', json=reset_data)
assert response.status_code == 200
print("✅ Password reset OTP sent")
print("🎉 All integration tests passed!")
if name == ‘main‘:
test_complete_auth_flow()`
🚀 Key Takeaways & Best Practices
What Made This Approach Successful:
Iterative Development: We built the system step-by-step, testing each component before moving forward
Context-Aware Prompting: Provided clear requirements and constraints to Copilot
Security-First Mindset: Always considered security implications in our prompts
Comprehensive Testing: Built tests alongside features, not as an afterthought
Production Readiness: Focused on real-world deployment considerations
Advanced Copilot Chat Tips:
Be Specific: Instead of “create authentication”, say “create JWT-based authentication with OTP verification”
Provide Context: Share your existing code structure and requirements
Ask for Alternatives: “What are the security implications of this approach?”
Request Explanations: “Why did you choose this implementation over alternatives?”
Iterate and Refine: Build on previous responses to improve the solution
📈 What’s Next?
Now that you have a solid foundation, consider extending the system with:
Two-Factor Authentication with TOTP
Social Login integration (Google, Facebook)
Advanced Rate Limiting with Redis
Audit Logging for security compliance
Microservices Architecture for scalability
GraphQL API for flexible data fetching
🏆 Conclusion
By following this guide, you’ve learned how to effectively collaborate with GitHub Copilot Chat to build production-grade software. The key is asking the right questions, providing proper context, and iteratively improving the solution.
The authentication system we built includes:
✅ 500+ lines of production-ready code
✅ Comprehensive test suite (95%+ coverage)
✅ Security best practices implementation
✅ Professional admin interface
✅ Complete API documentation
✅ Email integration with OTP
✅ JWT token management
✅ User role management
✅ Referral system foundation
Time saved: What typically takes 2-3 weeks was accomplished in a few hours with AI assistance!
Have you tried building authentication systems with AI assistance? Share your experience in the comments below! 👇
Found this helpful?
⭐ Star this article
🔄 Share with your developer community
📝 Let me know what authentication features you’d like to see next!