A production-ready .NET Core 8 Web API with email-based OTP authentication, JWT token management, and PostgreSQL integration.
✅ Email-based OTP Authentication
- Generate and send 6-digit OTP to email
- OTP expiration (configurable, default 5 minutes)
- Maximum attempt validation with email locking
- Auto-create user on first OTP verification
✅ JWT Token Management
- JWT-based session management
- Configurable token expiration
- Role-based access control (Requester, Provider, Admin)
- Token validation and user extraction
✅ User Management
- User registration with profile completion
- Role detection and assignment
- Profile status tracking
- Last login tracking
✅ Email Service
- SMTP configuration (Gmail, Office 365, custom)
- HTML email templates
- OTP, welcome, and password reset emails
- Error handling and retry logic
✅ Security Features
- CORS support for mobile frontends
- Email validation and phone number verification
- Account lockout after failed OTP attempts
- Secure password practices
✅ API Documentation
- Swagger/OpenAPI integration
- JWT Bearer authentication in Swagger UI
- Comprehensive endpoint documentation
- Health check endpoints
✅ Future-Ready Architecture
- Abstracted services for easy SMS OTP integration
- Extensible authentication flow
- Structured for mobile and web clients
ZentroAPI/
├── Models/ # Data models (User, OtpRecord)
├── DTOs/ # Data transfer objects
├── Data/ # Entity Framework DbContext
├── Services/ # Business logic services
│ ├── IOtpService # OTP generation and validation
│ ├── IEmailService # Email sending
│ ├── IJwtService # JWT token handling
│ └── IAuthService # Authentication business logic
├── Controllers/ # API endpoints
├── Program.cs # Application configuration
├── appsettings.json # Configuration
└── appsettings.Development.json
- .NET 8.0 SDK
- PostgreSQL 12 or higher
- Visual Studio 2022 or VS Code
git clone https://github.com/yourusername/ZentroAPI.git
cd ZentroAPIdotnet restoreUpdate appsettings.json with your PostgreSQL connection string:
"ConnectionStrings": {
"DefaultConnection": "Host=localhost;Port=5432;Database=zentro_db;Username=postgres;Password=your_password"
}Update appsettings.json with your email provider:
"EmailSettings": {
"SmtpHost": "smtp.gmail.com",
"SmtpPort": 587,
"SenderEmail": "your_email@gmail.com",
"SenderPassword": "your_app_password",
"SenderName": "Zentro"
}For Gmail:
- Use an App Password instead of your regular password
- Enable Less secure app access if needed
Update appsettings.json with secure JWT configuration:
"JwtSettings": {
"SecretKey": "your_super_secret_key_min_32_characters_long_!@#$%",
"Issuer": "ZentroAPI",
"Audience": "ZentroMobileApp",
"ExpirationMinutes": 1440
}dotnet ef migrations add InitialMigration
dotnet ef database updatedotnet runThe API will be available at https://localhost:5001 and Swagger UI at https://localhost:5001/swagger
POST /api/auth/send-otp
Content-Type: application/json
{
"email": "user@example.com",
"phoneNumber": "+1234567890"
}Response:
{
"success": true,
"message": "OTP sent successfully to your email",
"email": "user@example.com",
"expirationMinutes": 5
}POST /api/auth/verify-otp
Content-Type: application/json
{
"email": "user@example.com",
"otpCode": "123456"
}Response:
{
"success": true,
"message": "OTP verified successfully",
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"user": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "user@example.com",
"phoneNumber": "unknown",
"firstName": null,
"lastName": null,
"role": "Requester",
"isProfileComplete": false,
"isActive": true,
"createdAt": "2024-01-15T10:30:00Z"
},
"isNewUser": true
}POST /api/auth/register
Content-Type: application/json
{
"email": "user@example.com",
"firstName": "John",
"lastName": "Doe",
"phoneNumber": "+1234567890",
"role": "Requester"
}Response:
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "user@example.com",
"phoneNumber": "+1234567890",
"firstName": "John",
"lastName": "Doe",
"role": "Requester",
"isProfileComplete": true,
"isActive": true,
"createdAt": "2024-01-15T10:30:00Z",
"lastLoginAt": "2024-01-15T10:35:00Z"
}GET /api/auth/me
Authorization: Bearer <token>GET /api/health/ping
GET /api/health/status"OtpSettings": {
"ExpirationMinutes": 5,
"OtpLength": 6
}"Cors": {
"AllowedOrigins": [
"http://localhost:3000",
"http://localhost:8081",
"http://localhost:5173"
]
}Id(GUID, Primary Key)Email(VARCHAR, Unique)PhoneNumber(VARCHAR, Unique)FirstName(VARCHAR)LastName(VARCHAR)ProfileImageUrl(VARCHAR)Role(INT) - 0: Requester, 1: Provider, 2: AdminIsActive(BOOL)IsProfileComplete(BOOL)CreatedAt(TIMESTAMP)UpdatedAt(TIMESTAMP)LastLoginAt(TIMESTAMP)
Id(GUID, Primary Key)Email(VARCHAR)OtpCode(VARCHAR)ExpiresAt(TIMESTAMP)IsUsed(BOOL)UsedAt(TIMESTAMP)CreatedAt(TIMESTAMP)AttemptCount(INT)MaxAttempts(INT)IsLocked(BOOL)UserId(GUID, Foreign Key)Purpose(INT) - 0: Authentication, 1: PhoneVerification, 2: PasswordReset
To add SMS OTP support later:
- Create
ISmsServiceinterface - Implement SMS provider (Twilio, AWS SNS, etc.)
- Add SMS sending in
SendOtpAsyncmethod based on purpose - Update
OtpPurposeenum with phone verification specifics
- Create App Service and PostgreSQL database
- Update connection string in Azure Key Vault
- Deploy using Visual Studio or GitHub Actions
- Configure environment variables for JWT and email settings
- Create PostgreSQL database
- Set environment variables
- Deploy from GitHub
- Configure custom domain
- Use strong JWT secret key (32+ characters, random)
- Store secrets in Key Vault or secure configuration service
- Enable HTTPS only
- Use app-specific passwords for email service
- Implement rate limiting on OTP endpoints
- Add request logging and monitoring
- Configure proper CORS origins
- Use environment-specific configurations
- Enable database encryption
- Implement audit logging
- Check SMTP credentials
- Verify firewall allows outbound SMTP (port 587)
- Check email logs in application insights
- Verify sender email is authorized
- Confirm PostgreSQL is running
- Verify connection string format
- Check database user permissions
- Verify network connectivity
- Ensure secret key matches between generation and validation
- Check token expiration time
- Verify issuer and audience match
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit changes (
git commit -m 'Add amazing feature') - Push to branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License.
For issues and questions, please create an issue in the GitHub repository.
- SMS OTP integration (Twilio)
- Biometric authentication
- Two-factor authentication
- Social login integration (Google, Facebook)
- User profile management API
- Admin dashboard
- Analytics and reporting
- Multi-language support