This guide explains how to register users in the DePIN Scanner API with comprehensive security features.
- Database Setup: Run the SQL commands to create necessary tables
- Environment Configuration: Set up environment variables
- API Running: Ensure the FastAPI application is running
# Connect to your PostgreSQL database
psql -U your_username -d depin
# Run the setup SQL
\i setup_tables.sql# Copy and configure environment variables
cp .env.example .env
# Edit .env with your actual values
nano .env# Install dependencies
pip install -r requirements.txt
# Run the application
uvicorn main:app --reload --host 0.0.0.0 --port 8000- URL:
POST /api/v1/register - Rate Limit: 5 requests per hour per IP
- Security: Password breach checking, input validation, rate limiting
{
"email": "[email protected]",
"username": "johndoe",
"password": "MySecureP@ssw0rd123!",
"confirm_password": "MySecureP@ssw0rd123!",
"first_name": "John",
"last_name": "Doe",
"organization_name": "My Organization"
}Your password MUST meet all of the following criteria:
- β Minimum 12 characters (maximum 128)
- β At least 1 uppercase letter (A-Z)
- β At least 1 lowercase letter (a-z)
- β At least 1 digit (0-9)
- β At least 1 special character (!@#$%^&*()_+-=[]{}|;:,.<>?)
- β No common patterns (password, 123456, qwerty, admin, letmein)
- β Not found in data breaches (checked against HaveIBeenPwned)
- β 3-50 characters
- β Letters, numbers, hyphens, underscores only
- β Must be unique
- β Automatically converted to lowercase
curl -X POST "http://localhost:8000/api/v1/register" \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected]",
"username": "johndoe",
"password": "MySecureP@ssw0rd123!",
"confirm_password": "MySecureP@ssw0rd123!",
"first_name": "John",
"last_name": "Doe",
"organization_name": "Acme Corporation"
}'import requests
url = "http://localhost:8000/api/v1/register"
data = {
"email": "[email protected]",
"username": "johndoe",
"password": "MySecureP@ssw0rd123!",
"confirm_password": "MySecureP@ssw0rd123!",
"first_name": "John",
"last_name": "Doe",
"organization_name": "Acme Corporation"
}
response = requests.post(url, json=data)
print(response.json())const registerUser = async () => {
const response = await fetch('http://localhost:8000/api/v1/register', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
email: '[email protected]',
username: 'johndoe',
password: 'MySecureP@ssw0rd123!',
confirm_password: 'MySecureP@ssw0rd123!',
first_name: 'John',
last_name: 'Doe',
organization_name: 'Acme Corporation'
})
});
const result = await response.json();
console.log(result);
};{
"id": 1,
"uuid": "123e4567-e89b-12d3-a456-426614174000",
"email": "[email protected]",
"username": "johndoe",
"first_name": "John",
"last_name": "Doe",
"is_active": true,
"email_verified": false,
"created_at": "2025-06-24T10:30:00Z",
"message": "User account created successfully. Please verify your email address to complete registration."
}{
"detail": {
"message": "Password does not meet security requirements",
"issues": [
"Password must be at least 12 characters long",
"Password must contain at least one special character"
]
}
}{
"detail": {
"message": "Password has been found in data breaches",
"recommendation": "Please choose a different password that has not been compromised"
}
}{
"detail": "Email address is already registered"
}{
"detail": "Username is already taken"
}{
"detail": "Rate limit exceeded. Please try again later.",
"error_code": "RATE_LIMIT_EXCEEDED"
}- β BCrypt hashing with 14 rounds
- β Password breach checking via HaveIBeenPwned API
- β Complex password requirements
- β No password storage in plain text
- β 5 registration attempts per hour per IP
- β 10 login attempts per 15 minutes per IP
- β Automatic IP-based throttling
- β Email format validation
- β Username sanitization
- β SQL injection prevention
- β XSS protection
- β Account lockout after failed attempts
- β Email verification required
- β Audit logging for all actions
- β Automatic organization creation
When a user registers with an organization_name:
- New Organization Created with the user as admin
- Default Roles Assigned (admin, user, viewer)
- User Added to organization with admin role
- Organization UUID generated for API access
curl -X POST "http://localhost:8000/api/v1/login" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "username=johndoe&password=MySecureP@ssw0rd123!"curl -X GET "http://localhost:8000/api/v1/me" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"curl -X POST "http://localhost:8000/api/v1/organizations/YOUR_ORG_UUID/scan" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{"target": "example.com", "protocol_filter": "sui"}'-
"Database connection failed"
- Check DATABASE_URL in .env
- Ensure PostgreSQL is running
- Verify database credentials
-
"Password does not meet requirements"
- Review password criteria above
- Use a password manager to generate secure passwords
-
"Rate limit exceeded"
- Wait before retrying
- Check if multiple attempts from same IP
-
"Email already registered"
- User already exists
- Use login endpoint instead
- Try password reset if needed
Check the audit logs for security events:
-- View recent registration attempts
SELECT * FROM login_attempts
WHERE attempted_at > NOW() - INTERVAL '24 hours'
ORDER BY attempted_at DESC;
-- View audit events
SELECT * FROM audit_logs
WHERE action = 'user_registration'
ORDER BY created_at DESC
LIMIT 10;- Implement Email Verification (optional)
- Set up Password Reset (optional)
- Configure HTTPS for production
- Set up Monitoring for security events
- Backup Database regularly
- Change all default passwords
- Use strong JWT secrets (32+ characters)
- Enable HTTPS only
- Configure proper CORS origins
- Set up database backups
- Monitor rate limits and failed attempts
- Implement proper logging
- Regular security updates
# Generate secure secrets
SECRET_KEY=$(openssl rand -base64 32)
DATABASE_PASSWORD=$(openssl rand -base64 24)
REDIS_PASSWORD=$(openssl rand -base64 24)
# Update .env
echo "SECRET_KEY=$SECRET_KEY" >> .env
echo "ENVIRONMENT=production" >> .env
echo "DEBUG=False" >> .envπ Security is paramount! Always use HTTPS in production and keep your dependencies updated.