A complete microservices architecture with Authentication and Wallet services, built with Go, Gin, MongoDB, Redis, Apache Kafka, and JWT tokens. Designed for deployment on AWS EC2 with Nginx reverse proxy and SSL support.
This project implements a microservices architecture with the following services:
- User registration and login with email validation
- JWT-based authentication (7-day token expiry)
- Password hashing with bcrypt
- Redis caching for user profiles and sessions
- Token blacklisting on logout
- Rate limiting with Redis
- Digital wallet management
- Deposit and withdrawal operations
- Transaction history with pagination
- Balance inquiries
- Decimal precision for financial calculations
- Event-driven architecture with Kafka
- Apache Kafka for async messaging between services
- Auto wallet creation when users register
- Real-time transaction events
- Scalable event processing
- MongoDB for data persistence
- Redis for caching and session management
- Nginx reverse proxy with SSL/TLS
- Docker containerization
- AWS EC2 deployment ready
- Let's Encrypt SSL automation
- Go 1.21 or higher
- Docker and Docker Compose
- Git
- AWS EC2 instance (Amazon Linux 2 recommended)
- Domain name pointing to your EC2 instance
- SSH access to EC2 instance
-
Clone the repository
git clone <your-repository-url> cd auth-service
-
Install Go dependencies
go mod tidy
-
Start all microservices with Docker Compose
# Start all services (User + Wallet + MongoDB + Redis + Kafka) docker-compose up -d # View logs for all services docker-compose logs -f # View logs for specific service docker-compose logs -f user-service docker-compose logs -f wallet-service docker-compose logs -f kafka # Check service status docker-compose ps
-
Verify installation
# Health check curl http://localhost:8080/health # Expected response: {"status":"healthy"}
-
Stop services
docker-compose down
- Launch Amazon Linux 2 EC2 instance
- Configure Security Group:
- Port 22 (SSH)
- Port 80 (HTTP)
- Port 443 (HTTPS)
- Connect via SSH
# Option 1: Using SCP
scp -r -i your-key.pem . ec2-user@your-ec2-ip:/home/ec2-user/auth-service
# Option 2: Using Git (recommended)
ssh -i your-key.pem ec2-user@your-ec2-ip
git clone <your-repository-url>
cd auth-service
# Make deployment script executable
chmod +x deploy-production.sh
# Run production deployment
./deploy-production.sh
# This script will:
# - Install Docker and Docker Compose
# - Generate secure credentials
# - Build and start services with Nginx
# - Display next steps for SSL setup
# Edit SSL setup script with your domain and email
nano ssl-setup.sh
# Update these variables:
# DOMAIN="your-domain.com"
# EMAIL="[email protected]"
# Run SSL setup
chmod +x ssl-setup.sh
./ssl-setup.sh
# This will:
# - Install Let's Encrypt certbot
# - Obtain SSL certificates
# - Configure auto-renewal
# - Restart services with SSL
GET /health
- Health checkPOST /api/v1/register
- User registrationPOST /api/v1/login
- User login
POST /api/v1/logout
- User logout (blacklists token)GET /api/v1/profile
- Get user profile (cached)PUT /api/v1/profile
- Update user profile (invalidates cache)
POST /api/v1/wallet
- Create walletGET /api/v1/wallet/{user_id}
- Get wallet detailsGET /api/v1/wallet/{user_id}/balance
- Get wallet balance
POST /api/v1/wallet/{user_id}/deposit
- Deposit moneyPOST /api/v1/wallet/{user_id}/withdraw
- Withdraw moneyGET /api/v1/wallet/{user_id}/transactions
- Transaction history (paginated)
Local Development (http://localhost:8080)
curl -X POST http://localhost:8080/api/v1/register \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected]",
"password": "password123",
"first_name": "John",
"last_name": "Doe"
}'
curl -X POST http://localhost:8080/api/v1/login \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected]",
"password": "password123"
}'
# Response includes JWT token:
# {
# "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
# "user": { ... }
# }
# Save token from login response
TOKEN="your-jwt-token-here"
curl -X GET http://localhost:8080/api/v1/profile \
-H "Authorization: Bearer $TOKEN"
curl -X PUT http://localhost:8080/api/v1/profile \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"first_name": "Jane",
"last_name": "Smith"
}'
curl -X POST http://localhost:8080/api/v1/logout \
-H "Authorization: Bearer $TOKEN"
# Response: {"message": "logged out successfully"}
Wallet Service Examples (http://localhost:8081)
curl -X POST http://localhost:8081/api/v1/wallet \
-H "Content-Type: application/json" \
-d '{
"user_id": "USER_ID_FROM_REGISTRATION",
"currency": "USD"
}'
curl -X POST http://localhost:8081/api/v1/wallet/USER_ID/deposit \
-H "Content-Type: application/json" \
-d '{
"amount": "100.50",
"description": "Initial deposit",
"reference_id": "DEP001"
}'
curl -X POST http://localhost:8081/api/v1/wallet/USER_ID/withdraw \
-H "Content-Type: application/json" \
-d '{
"amount": "25.00",
"description": "ATM withdrawal",
"reference_id": "WTH001"
}'
curl -X GET http://localhost:8081/api/v1/wallet/USER_ID/balance
# Response: {
# "user_id": "USER_ID",
# "balance": "75.50",
# "currency": "USD",
# "status": "active"
# }
curl -X GET "http://localhost:8081/api/v1/wallet/USER_ID/transactions?page=1&limit=10"
# Response: {
# "transactions": [...],
# "total": 5,
# "page": 1,
# "limit": 10
# }
Production (https://your-domain.com)
Replace http://localhost:8080
with https://your-domain.com
in all examples above.
# Example for production
curl -X POST https://your-domain.com/api/v1/register \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected]",
"password": "password123",
"first_name": "John",
"last_name": "Doe"
}'
# Auth Service
MONGO_URI=mongodb://localhost:27017/auth_db
JWT_SECRET=your-super-secret-jwt-key-change-this-in-production
PORT=8080
GIN_MODE=debug
REDIS_ADDR=redis:6379
REDIS_PASSWORD=
KAFKA_BROKERS=localhost:9092
# Wallet Service (separate .env in wallet-service/)
MONGO_URI=mongodb://localhost:27017/wallet_db
PORT=8081
KAFKA_BROKERS=localhost:9092
JWT_SECRET=<auto-generated-64-char-secret>
MONGO_ROOT_USER=admin
MONGO_ROOT_PASSWORD=<auto-generated-password>
REDIS_PASSWORD=<auto-generated-password>
GIN_MODE=release
KAFKA_BROKERS=kafka:9092
# Local
docker-compose ps
docker-compose logs -f
# Production
docker-compose -f docker-compose.prod.yml ps
docker-compose -f docker-compose.prod.yml logs -f
# Local
docker-compose restart
# Production
docker-compose -f docker-compose.prod.yml restart
docker-compose -f docker-compose.prod.yml logs nginx
# Connect to MongoDB container
docker-compose exec mongo mongosh
# Or with authentication (production)
docker-compose -f docker-compose.prod.yml exec mongo mongosh -u admin -p
# Connect to Redis container (local)
docker-compose exec redis redis-cli
# Connect to Redis container (production with password)
docker-compose -f docker-compose.prod.yml exec redis redis-cli -a your-redis-password
# Check Redis stats
docker-compose exec redis redis-cli info memory
- JWT token-based authentication
- Password hashing with bcrypt (cost 12)
- Token expiry (7 days)
- Token blacklisting on logout
- Session management with Redis
- Protected route middleware
- Redis caching for user profiles (15-minute TTL)
- Session storage in Redis
- Rate limiting with Redis counters
- Database query optimization
- Connection pooling
- Nginx reverse proxy
- SSL/TLS encryption (Let's Encrypt)
- HTTP to HTTPS redirect
- Security headers (HSTS, XSS protection, etc.)
- General API: 10 requests/second
- Login endpoint: 5 requests/minute (per IP)
- Burst protection enabled
- Redis-based rate limiting
- Email format validation
- Password minimum length (6 characters)
- JSON schema validation
- SQL injection prevention
# Check logs
docker-compose logs
# Check if ports are in use
sudo netstat -tlnp | grep :8080
sudo netstat -tlnp | grep :27017
# Check certificate status
sudo certbot certificates
# Test SSL configuration
curl -I https://your-domain.com/health
# Renew certificates manually
sudo certbot renew --dry-run
# Check MongoDB logs
docker-compose logs mongo
# Test connection
docker-compose exec auth-service ping mongo
# Check Redis logs
docker-compose logs redis
# Test Redis connection
docker-compose exec redis redis-cli ping
# Check Redis memory usage
docker-compose exec redis redis-cli info memory
# Clear all Redis cache
docker-compose exec redis redis-cli FLUSHALL
# Check specific cache keys
docker-compose exec redis redis-cli KEYS "user:*"
docker-compose exec redis redis-cli KEYS "session:*"
docker-compose exec redis redis-cli KEYS "rate_limit:*"
# Monitor resource usage
docker stats
# Check API response times
curl -w "@curl-format.txt" -o /dev/null -s https://your-domain.com/health
- ✅ Change default JWT secret
- ✅ Use strong MongoDB passwords
- ✅ Use strong Redis passwords
- ✅ Enable SSL/TLS
- ✅ Configure rate limiting
- ✅ Set up security headers
- ✅ Token blacklisting on logout
- ✅ Session management
- ✅ Regular security updates
- Use MongoDB Atlas for managed database
- Use Redis Cluster or AWS ElastiCache for Redis
- Set up load balancer for multiple instances
- Configure horizontal pod autoscaling
- Implement database read replicas
- Set up CloudWatch monitoring
- Configure log aggregation
- Set up health check alerts
- Monitor SSL certificate expiry
- Automated MongoDB backups
- Database replication
- Disaster recovery plan
- Regular backup testing
- User profiles are cached for 15 minutes after first access
- Cache is automatically invalidated when profile is updated
- Reduces database load for frequent profile requests
- User sessions stored in Redis with 7-day expiry
- Session data includes login time and IP address
- Sessions are deleted on logout
- Logout blacklists JWT tokens until their natural expiry
- Prevents token reuse after logout
- Automatic cleanup when tokens expire
- IP-based rate limiting using Redis counters
- Login attempts: 5 per 5 minutes per IP
- General API: 10 requests per second per IP
- Automatic reset after time window
user:{user_id} # User profile cache
session:{user_id} # User session data
blacklist:{token_id} # Blacklisted tokens
rate_limit:login:{ip} # Login rate limiting
rate_limit:{identifier} # General rate limiting
- Profile Requests: ~90% faster with cache hit
- Rate Limiting: Distributed across multiple instances
- Session Validation: No database queries needed
- Token Security: Immediate logout enforcement
# Make the test script executable
chmod +x microservices-test.sh
# Run the complete integration test
./microservices-test.sh
# This will test:
# 1. User registration
# 2. User login
# 3. Auto wallet creation via Kafka
# 4. Deposit transaction
# 5. Withdraw transaction
# 6. Balance check
# 7. Transaction history
# 8. User profile access
# 9. User logout
# 1. Register user
curl -X POST http://localhost:8080/api/v1/register \
-H "Content-Type: application/json" \
-d '{"email": "[email protected]", "password": "password123", "first_name": "John", "last_name": "Doe"}'
# 2. Wait 5 seconds for Kafka event processing
# 3. Check if wallet was auto-created
curl -X GET http://localhost:8081/api/v1/wallet/USER_ID
# 4. Deposit money
curl -X POST http://localhost:8081/api/v1/wallet/USER_ID/deposit \
-H "Content-Type: application/json" \
-d '{"amount": "100.00", "description": "Test deposit"}'
# 5. Check balance
curl -X GET http://localhost:8081/api/v1/wallet/USER_ID/balance
- user-events - User lifecycle events (registration, deletion)
- wallet-events - Wallet lifecycle events (creation, status changes)
- transaction-events - Transaction events (deposits, withdrawals)
User Registration → Kafka Event → Auto Wallet Creation
Transaction → Kafka Event → Audit/Analytics
User Deletion → Kafka Event → Wallet Suspension
// User Registered Event
{
"type": "user.registered",
"user_id": "507f1f77bcf86cd799439011",
"email": "[email protected]",
"first_name": "John",
"last_name": "Doe",
"timestamp": "2024-01-15T10:30:00Z"
}
// Transaction Event
{
"user_id": "507f1f77bcf86cd799439011",
"wallet_id": "507f1f77bcf86cd799439012",
"transaction_id": "507f1f77bcf86cd799439013",
"type": "deposit",
"amount": 100.50,
"currency": "USD",
"status": "completed",
"timestamp": "2024-01-15T10:35:00Z"
}
For issues and questions:
- Check the troubleshooting section
- Review Docker and service logs
- Verify environment configuration
- Check AWS Security Group settings
- Monitor Redis cache performance
- Check Kafka topic messages and consumer groups