A Production-Grade JWT Authentication System with RBAC, Session Management, and Security Features
A comprehensive, production-ready authentication system built with FastAPI that implements modern security best practices including JWT tokens, HttpOnly cookies, role-based access control (RBAC), session management, and advanced security features.
- JWT Access & Refresh Tokens with automatic rotation
- HttpOnly Secure Cookies for token storage
- Token Reuse Detection with family-based revocation
- Device Fingerprinting based on IP + User-Agent
- Role-Based Access Control (RBAC) with 4 roles:
USER: Basic accessSUPPORT: Ticket managementMANAGER: User management + logsADMIN: Full system access
- Password Hashing with bcrypt (12 rounds)
- Account Lockout after 5 failed login attempts
- Rate Limiting on all sensitive endpoints
- Session Management with per-device tracking
- Security Logging for all authentication events
- CSRF Protection via SameSite cookies
- Maximum Sessions Per User (configurable)
- Auto-login on Register for better UX
- Token Refresh without re-authentication
- Multi-session Support with individual revocation
- Swagger UI with automatic documentation
- Async SQLAlchemy with PostgreSQL/SQLite support
- Alembic Migrations for database versioning
- Python 3.12+
- PostgreSQL (or SQLite for development)
- Redis (optional, for production rate limiting)
# Clone the repository
git clone https://github.com/moeinrezai/FastAPI-Authentication.git
cd fastapi-auth-system
# Create virtual environment
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install dependencies
pip install -r requirements.txt
# Set up environment variables
cp .env.example .env
# Edit .env with your settings
# Run migrations
python -m alembic upgrade head
# Start the server
fastapi devCreate a .env file:
# Database
DATABASE_URL=sqlite+aiosqlite:///./data/app.db
# JWT
SECRET_KEY=your-secret-key-min-32-chars-long
JWT_ALGORITHM=HS256
ACCESS_TOKEN_EXPIRE_MINUTES=30
REFRESH_TOKEN_EXPIRE_DAYS=7
# Cookie Security
COOKIE_SECURE=false # Set to true in production
COOKIE_SAMESITE=lax
# Security
MAX_SESSIONS_PER_USER=3
MAX_LOGIN_ATTEMPTS=5
LOCKOUT_DURATION_MINUTES=15
BCRYPT_ROUNDS=12
# Rate Limits
RATE_LIMIT_REGISTER=5/minute
RATE_LIMIT_LOGIN=10/minute
RATE_LIMIT_REFRESH=20/minute
RATE_LIMIT_LOGOUT=20/minute
# Environment
ENVIRONMENT=development
DEBUG=trueThe project includes a comprehensive CLI for user management:
# Create users
python -m app.scripts.cli create-user --email user@example.com
python -m app.scripts.cli create-admin --email admin@example.com
python -m app.scripts.cli create-manager --email manager@example.com
python -m app.scripts.cli create-support --email support@example.com
# User management
python -m app.scripts.cli list-users
python -m app.scripts.cli change-role --email user@example.com --role admin
python -m app.scripts.cli reset-password --email user@example.com
python -m app.scripts.cli activate-user --email user@example.com
python -m app.scripts.cli deactivate-user --email user@example.com# Run all tests
python -m pytest -v
# Run with coverage
python -m pytest -v --cov=app --cov-report=term-missing
# Run specific test file
python -m pytest tests/test_auth.py -vLatest test run:
- ✅ 106 passed
⚠️ 5 warnings- ⏱️ 70.52 seconds
- 📊 64% total code coverage
- 🐍 Python 3.12.7
- 🧪 pytest 9.1.1
- 🔌 pytest-asyncio 1.4.0
- 📦 106 test cases collected
- ❌ 0 failed
- ⏭️ 0 skipped
| Test file | Tests | Result |
|---|---|---|
tests/test_admin.py |
31 | ✅ 31 passed |
tests/test_auth.py |
29 | ✅ 29 passed |
tests/test_sessions.py |
10 | ✅ 10 passed |
tests/test_tickets.py |
23 | ✅ 23 passed |
tests/test_users.py |
13 | ✅ 13 passed |
| Total | 106 | ✅ 106 passed |
| Module | Coverage |
|---|---|
app/api/v1/endpoints/admin.py |
68% |
app/api/v1/endpoints/auth.py |
78% |
app/api/v1/endpoints/sessions.py |
76% |
app/api/v1/endpoints/tickets.py |
93% |
app/api/v1/endpoints/users.py |
100% |
app/core/config.py |
100% |
app/core/permissions.py |
71% |
app/core/security.py |
84% |
app/dependencies.py |
78% |
app/main.py |
93% |
app/models/session.py |
95% |
app/models/ticket.py |
100% |
app/models/ticket_reply.py |
100% |
app/models/token.py |
100% |
app/models/user.py |
100% |
app/schemas/auth.py |
96% |
app/schemas/session.py |
100% |
app/schemas/ticket.py |
100% |
app/schemas/user.py |
100% |
app/services/auth_service.py |
38% |
app/services/session_service.py |
50% |
app/services/ticket_service.py |
44% |
app/services/user_service.py |
49% |
| TOTAL | 64% |
The supplied test run also reported 5
DeprecationWarningwarnings from HTTPX regarding per-request cookie handling. These warnings did not cause any test failure.
View the exact pytest output
(venv) PS D:\FastAPI Authentication\project> python -m pytest -v --cov=app --cov-report=term-missing
============================================================= test session starts =============================================================
platform win32 -- Python 3.12.7, pytest-9.1.1, pluggy-1.6.0 -- C:\Users\Npc\AppData\Local\Programs\Python\Python312\python.exe
cachedir: .pytest_cache
rootdir: D:\FastAPI Authentication\project
configfile: pytest.ini
plugins: anyio-4.14.1, Faker-40.36.0, asyncio-1.4.0, cov-4.1.0, django-4.7.0
asyncio: mode=Mode.STRICT, debug=False, asyncio_default_fixture_loop_scope=None, asyncio_default_test_loop_scope=function
collected 106 items
tests/test_admin.py::TestListUsers::test_list_users_as_admin PASSED [ 0%]
tests/test_admin.py::TestListUsers::test_list_users_as_manager PASSED [ 1%]
tests/test_admin.py::TestListUsers::test_list_users_as_regular_user PASSED [ 2%]
tests/test_admin.py::TestListUsers::test_list_users_as_support_fails PASSED [ 3%]
tests/test_admin.py::TestListUsers::test_list_users_unauthorized PASSED [ 4%]
tests/test_admin.py::TestListUsers::test_list_users_pagination PASSED [ 5%]
tests/test_admin.py::TestGetUser::test_get_user_as_admin PASSED [ 6%]
tests/test_admin.py::TestGetUser::test_get_user_as_manager PASSED [ 7%]
tests/test_admin.py::TestGetUser::test_get_user_as_regular_user PASSED [ 8%]
tests/test_admin.py::TestGetUser::test_get_user_not_found PASSED [ 9%]
tests/test_admin.py::TestUpdateUserStatus::test_deactivate_user PASSED [ 10%]
tests/test_admin.py::TestUpdateUserStatus::test_activate_user PASSED [ 11%]
tests/test_admin.py::TestUpdateUserStatus::test_deactivate_user_as_manager PASSED [ 12%]
tests/test_admin.py::TestUpdateUserStatus::test_deactivate_user_as_regular_user PASSED [ 13%]
tests/test_admin.py::TestChangeUserRole::test_change_role_as_admin PASSED [ 14%]
tests/test_admin.py::TestChangeUserRole::test_change_role_as_manager_fails PASSED [ 15%]
tests/test_admin.py::TestChangeUserRole::test_change_role_as_regular_user_fails PASSED [ 16%]
tests/test_admin.py::TestChangeUserRole::test_change_role_invalid_role PASSED [ 16%]
tests/test_admin.py::TestCreateUserByAdmin::test_create_user_as_admin PASSED [ 17%]
tests/test_admin.py::TestCreateUserByAdmin::test_create_user_as_manager_fails PASSED [ 18%]
tests/test_admin.py::TestCreateUserByAdmin::test_create_user_duplicate_email PASSED [ 19%]
tests/test_admin.py::TestDeleteUser::test_delete_user_as_admin PASSED [ 20%]
tests/test_admin.py::TestDeleteUser::test_delete_user_as_manager_fails PASSED [ 21%]
tests/test_admin.py::TestDeleteUser::test_delete_user_as_regular_user PASSED [ 22%]
tests/test_admin.py::TestDeleteUser::test_delete_self_fails PASSED [ 23%]
tests/test_admin.py::TestAdminLogs::test_get_logs_as_admin PASSED [ 24%]
tests/test_admin.py::TestAdminLogs::test_get_logs_as_manager PASSED [ 25%]
tests/test_admin.py::TestAdminLogs::test_get_logs_as_regular_user PASSED [ 26%]
tests/test_admin.py::TestAdminLogs::test_get_logs_as_support_fails PASSED [ 27%]
tests/test_admin.py::TestAdminLogs::test_get_logs_pagination PASSED [ 28%]
tests/test_admin.py::TestAdminLogs::test_logs_contain_login_events PASSED [ 29%]
tests/test_auth.py::TestRegister::test_register_success PASSED [ 30%]
tests/test_auth.py::TestRegister::test_register_duplicate_email PASSED [ 31%]
tests/test_auth.py::TestRegister::test_register_password_mismatch PASSED [ 32%]
tests/test_auth.py::TestRegister::test_register_weak_password_too_short PASSED [ 33%]
tests/test_auth.py::TestRegister::test_register_weak_password_no_uppercase PASSED [ 33%]
tests/test_auth.py::TestRegister::test_register_weak_password_no_lowercase PASSED [ 34%]
tests/test_auth.py::TestRegister::test_register_weak_password_no_digit PASSED [ 35%]
tests/test_auth.py::TestRegister::test_register_weak_password_no_special_char PASSED [ 36%]
tests/test_auth.py::TestRegister::test_register_invalid_email PASSED [ 37%]
tests/test_auth.py::TestLogin::test_login_success PASSED [ 38%]
tests/test_auth.py::TestLogin::test_login_wrong_password PASSED [ 39%]
tests/test_auth.py::TestLogin::test_login_nonexistent_user PASSED [ 40%]
tests/test_auth.py::TestLogin::test_login_empty_password PASSED [ 41%]
tests/test_auth.py::TestLogin::test_login_short_email PASSED [ 42%]
tests/test_auth.py::TestLogin::test_login_invalid_email_format PASSED [ 43%]
tests/test_auth.py::TestRefresh::test_refresh_success PASSED [ 44%]
tests/test_auth.py::TestRefresh::test_refresh_missing_cookie PASSED [ 45%]
tests/test_auth.py::TestRefresh::test_refresh_invalid_token PASSED [ 46%]
tests/test_auth.py::TestRefresh::test_refresh_token_reuse_detection PASSED [ 47%]
tests/test_auth.py::TestLogout::test_logout_success PASSED [ 48%]
tests/test_auth.py::TestLogout::test_logout_without_cookie PASSED [ 49%]
tests/test_auth.py::TestLogout::test_logout_all_success PASSED [ 50%]
tests/test_auth.py::TestPasswordChange::test_change_password_success PASSED [ 50%]
tests/test_auth.py::TestPasswordChange::test_change_password_wrong_old PASSED [ 51%]
tests/test_auth.py::TestPasswordChange::test_change_password_same_as_old PASSED [ 52%]
tests/test_auth.py::TestPasswordChange::test_change_password_mismatch PASSED [ 53%]
tests/test_auth.py::TestPasswordChange::test_change_password_weak_new PASSED [ 54%]
tests/test_auth.py::TestPasswordChange::test_change_password_unauthorized PASSED [ 55%]
tests/test_auth.py::TestHealth::test_health_check PASSED [ 56%]
tests/test_sessions.py::TestListSessions::test_list_sessions_success PASSED [ 57%]
tests/test_sessions.py::TestListSessions::test_list_sessions_contains_current PASSED [ 58%]
tests/test_sessions.py::TestListSessions::test_list_sessions_unauthorized PASSED [ 59%]
tests/test_sessions.py::TestListSessions::test_list_sessions_invalid_token PASSED [ 60%]
tests/test_sessions.py::TestListSessions::test_list_sessions_empty_for_new_user PASSED [ 61%]
tests/test_sessions.py::TestListSessions::test_multiple_sessions PASSED [ 62%]
tests/test_sessions.py::TestRevokeSession::test_revoke_current_session_fails PASSED [ 63%]
tests/test_sessions.py::TestRevokeSession::test_revoke_nonexistent_session PASSED [ 64%]
tests/test_sessions.py::TestRevokeSession::test_revoke_session_unauthorized PASSED [ 65%]
tests/test_sessions.py::TestRevokeSession::test_revoke_other_users_session_fails PASSED [ 66%]
tests/test_tickets.py::TestCreateTicket::test_create_ticket_success PASSED [ 66%]
tests/test_tickets.py::TestCreateTicket::test_create_ticket_unauthorized PASSED [ 67%]
tests/test_tickets.py::TestCreateTicket::test_create_ticket_subject_too_short PASSED [ 68%]
tests/test_tickets.py::TestCreateTicket::test_create_ticket_description_too_short PASSED [ 69%]
tests/test_tickets.py::TestCreateTicket::test_create_ticket_support_role_fails PASSED [ 70%]
tests/test_tickets.py::TestListTickets::test_list_tickets_as_user PASSED [ 71%]
tests/test_tickets.py::TestListTickets::test_list_tickets_only_own PASSED [ 72%]
tests/test_tickets.py::TestListTickets::test_list_tickets_as_support_sees_all PASSED [ 73%]
tests/test_tickets.py::TestListTickets::test_list_tickets_unauthorized PASSED [ 74%]
tests/test_tickets.py::TestGetTicket::test_get_ticket_as_owner PASSED [ 75%]
tests/test_tickets.py::TestGetTicket::test_get_ticket_as_other_user_fails PASSED [ 76%]
tests/test_tickets.py::TestGetTicket::test_get_ticket_as_support PASSED [ 77%]
tests/test_tickets.py::TestGetTicket::test_get_ticket_not_found PASSED [ 78%]
tests/test_tickets.py::TestReplyToTicket::test_reply_as_owner PASSED [ 79%]
tests/test_tickets.py::TestReplyToTicket::test_reply_as_support_updates_status PASSED [ 80%]
tests/test_tickets.py::TestReplyToTicket::test_reply_as_other_user_fails PASSED [ 81%]
tests/test_tickets.py::TestReplyToTicket::test_reply_empty_message_fails PASSED [ 82%]
tests/test_tickets.py::TestReplyToTicket::test_reply_nonexistent_ticket PASSED [ 83%]
tests/test_tickets.py::TestDeleteTicket::test_delete_ticket_as_admin PASSED [ 83%]
tests/test_tickets.py::TestDeleteTicket::test_delete_ticket_as_manager PASSED [ 84%]
tests/test_tickets.py::TestDeleteTicket::test_delete_ticket_as_support_fails PASSED [ 85%]
tests/test_tickets.py::TestDeleteTicket::test_delete_ticket_as_regular_user_fails PASSED [ 86%]
tests/test_tickets.py::TestDeleteTicket::test_delete_ticket_not_found PASSED [ 87%]
tests/test_users.py::TestGetProfile::test_get_profile_success PASSED [ 88%]
tests/test_users.py::TestGetProfile::test_get_profile_unauthorized PASSED [ 89%]
tests/test_users.py::TestGetProfile::test_get_profile_invalid_token PASSED [ 90%]
tests/test_users.py::TestGetProfile::test_get_profile_refresh_token_as_bearer PASSED [ 91%]
tests/test_users.py::TestUpdateProfile::test_update_username PASSED [ 92%]
tests/test_users.py::TestUpdateProfile::test_update_email PASSED [ 93%]
tests/test_users.py::TestUpdateProfile::test_update_both PASSED [ 94%]
tests/test_users.py::TestUpdateProfile::test_update_email_duplicate PASSED [ 95%]
tests/test_users.py::TestUpdateProfile::test_update_username_duplicate PASSED [ 96%]
tests/test_users.py::TestUpdateProfile::test_update_invalid_email PASSED [ 97%]
tests/test_users.py::TestUpdateProfile::test_update_invalid_username PASSED [ 98%]
tests/test_users.py::TestUpdateProfile::test_update_username_too_short PASSED [ 99%]
tests/test_users.py::TestUpdateProfile::test_update_unauthorized PASSED [100%]
============================================================== warnings summary ===============================================================
tests/test_auth.py::TestRefresh::test_refresh_success
tests/test_auth.py::TestRefresh::test_refresh_invalid_token
tests/test_auth.py::TestRefresh::test_refresh_token_reuse_detection
tests/test_auth.py::TestRefresh::test_refresh_token_reuse_detection
tests/test_auth.py::TestLogout::test_logout_success
C:\Users\Npc\AppData\Local\Programs\Python\Python312\Lib\site-packages\httpx\_client.py:1859: DeprecationWarning: Setting per-request cookies=<...> is being deprecated, because the expected behaviour on cookie persistence is ambiguous. Set cookies directly on the client instance instead.
return await self.request(
-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
---------- coverage: platform win32, python 3.12.7-final-0 -----------
Name Stmts Miss Cover Missing
----------------------------------------------------------------
app\__init__.py 0 0 100%
app\api\__init__.py 0 0 100%
app\api\v1\__init__.py 0 0 100%
app\api\v1\endpoints\__init__.py 2 0 100%
app\api\v1\endpoints\admin.py 62 20 68% 49-72, 86, 109, 124-127, 141-142, 162-163
app\api\v1\endpoints\auth.py 85 19 78% 85, 109-118, 140-146, 174-180, 220-224, 245-249
app\api\v1\endpoints\sessions.py 25 6 76% 38-44, 62
app\api\v1\endpoints\tickets.py 30 2 93% 54, 89
app\api\v1\endpoints\users.py 15 0 100%
app\core\__init__.py 5 0 100%
app\core\config.py 30 0 100%
app\core\permissions.py 14 4 71% 66, 70, 74, 78
app\core\rate_limit.py 3 0 100%
app\core\security.py 49 8 84% 23-24, 100-112
app\db\__init__.py 3 0 100%
app\db\base.py 3 0 100%
app\db\session.py 10 4 60% 20-24
app\dependencies.py 80 18 78% 30, 65-85, 92, 134, 138, 142, 150, 159, 163
app\main.py 27 2 93% 18-19
app\models\__init__.py 7 0 100%
app\models\log.py 13 0 100%
app\models\session.py 21 1 95% 15
app\models\ticket.py 21 0 100%
app\models\ticket_reply.py 14 0 100%
app\models\ticket_status.py 5 5 0% 1-7
app\models\token.py 10 0 100%
app\models\user.py 21 0 100%
app\models\user_role.py 6 0 100%
app\schemas\__init__.py 5 0 100%
app\schemas\auth.py 57 2 96% 8, 10
app\schemas\session.py 15 0 100%
app\schemas\ticket.py 30 0 100%
app\schemas\user.py 25 0 100%
app\scripts\__init__.py 0 0 100%
app\scripts\cli.py 161 161 0% 15-243
app\services\__init__.py 5 0 100%
app\services\auth_service.py 157 97 38% 33, 62-88, 93-94, 103-106, 116-121, 132-158, 169-198, 221-289, 300, 305-310, 322-326, 346-354
app\services\session_service.py 24 12 50% 23, 33, 44-63
app\services\ticket_service.py 50 28 44% 23-24, 36, 48-63, 70-97, 102-111
app\services\user_service.py 49 25 49% 14-20, 31-37, 41-51, 60-65, 71-72, 85-90
----------------------------------------------------------------
TOTAL 1139 414 64%
================================================= 106 passed, 5 warnings in 70.52s (0:01:10) ==================================================
(venv) PS D:\FastAPI Authentication\project>
POST /api/v1/auth/register- User registration (auto-login)POST /api/v1/auth/login- User loginPOST /api/v1/auth/refresh- Refresh access tokenPOST /api/v1/auth/logout- Logout current sessionPOST /api/v1/auth/logout-all- Logout all sessionsPUT /api/v1/auth/password- Change password
GET /api/v1/users/me- Get current user profilePUT /api/v1/users/me- Update profile
GET /api/v1/sessions- List active sessionsDELETE /api/v1/sessions/{id}- Revoke specific session
GET /api/v1/admin/users- List all usersPOST /api/v1/admin/users- Create user (Admin only)GET /api/v1/admin/users/{id}- Get user detailsPATCH /api/v1/admin/users/{id}/status- Activate/deactivate userPATCH /api/v1/admin/users/{id}/role- Change user role (Admin only)DELETE /api/v1/admin/users/{id}- Delete user (Admin only)GET /api/v1/admin/logs- View security logs
POST /api/v1/tickets- Create ticketGET /api/v1/tickets- List ticketsGET /api/v1/tickets/{id}- Get ticket detailsPOST /api/v1/tickets/{id}/reply- Reply to ticketDELETE /api/v1/tickets/{id}- Delete ticket (Admin/Manager)
The following screenshots demonstrate the main authentication, session, user, ticket, and logout flows through Swagger UI.
Add the screenshots to
docs/screenshots/using the filenames below. The README references these files directly.
| Flow | Screenshot |
|---|---|
| Register | docs/screenshots/01-register.png |
| Login | docs/screenshots/02-login.png |
| Sessions | docs/screenshots/03-sessions.png |
| Current User | docs/screenshots/04-user.png |
| Create Ticket | docs/screenshots/05-ticket-create.png |
| Reply to Ticket | docs/screenshots/06-ticket-reply.png |
| Logout | docs/screenshots/07-logout.png |
For the complete screenshot checklist and recommended order, see docs/SWAGGER.md.
project/
├── app/
│ ├── api/v1/endpoints/ # API route handlers
│ ├── core/ # Core modules (config, security, permissions)
│ ├── db/ # Database models and session
│ ├── models/ # SQLAlchemy models
│ ├── schemas/ # Pydantic schemas
│ ├── scripts/ # CLI scripts
│ ├── services/ # Business logic
│ └── main.py # FastAPI app
├── tests/ # Test files
|
├── alembic/ # Database migrations
├── data/ # SQLite database (dev)
├── requirements.txt # Python dependencies
├── pytest.ini # Pytest configuration
└── .env # Environment variables
|
├── docs/
│ └── screenshots/ # Swagger UI screenshots
-
Password Security
- Bcrypt hashing with 12 rounds
- Password strength validation
- No passwords in JWT tokens
-
Token Security
- Short-lived access tokens (30 min)
- Long-lived refresh tokens (7 days)
- Token rotation on refresh
- Family-based revocation for reuse detection
-
Session Security
- Device fingerprinting
- Maximum sessions per user
- Individual session revocation
- Session expiration
-
Cookie Security
- HttpOnly flag (no JavaScript access)
- Secure flag (HTTPS only in production)
- SameSite attribute (CSRF protection)
- Path restriction
-
Rate Limiting
- Per-endpoint rate limits
- Configurable limits
- IP-based tracking
- Async Architecture: All database operations are async
- Connection Pooling: SQLAlchemy connection pooling enabled
- Query Optimization: Efficient queries with proper indexing
- Caching Ready: Easy to add Redis caching layer
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["fastapi", "run", "app/main.py", "--host", "0.0.0.0", "--port", "8000"]ENVIRONMENT=production
DEBUG=false
COOKIE_SECURE=true
COOKIE_SAMESITE=strict
DATABASE_URL=postgresql+asyncpg://user:pass@host:5432/db- Swagger UI: http://localhost:8000/docs
- ReDoc: http://localhost:8000/redoc
- OpenAPI JSON: http://localhost:8000/openapi.json
یک سیستم احراز هویت جامع و آماده برای محیط production که با FastAPI ساخته شده و بهترین شیوههای امنیتی مدرن از جمله JWT tokens، کوکیهای HttpOnly، کنترل دسترسی مبتنی بر نقش (RBAC)، مدیریت session و ویژگیهای امنیتی پیشرفته را پیادهسازی میکند.
- JWT Access و Refresh Token با چرخش خودکار
- کوکیهای امن HttpOnly برای ذخیره توکن
- تشخیص استفاده مجدد از توکن با ابطال مبتنی بر family
- اثر انگشت دستگاه بر اساس IP + User-Agent
- کنترل دسترسی مبتنی بر نقش (RBAC) با ۴ نقش:
USER: دسترسی پایهSUPPORT: مدیریت تیکتMANAGER: مدیریت کاربران + لاگهاADMIN: دسترسی کامل به سیستم
- هش کردن رمز عبور با bcrypt (۱۲ دور)
- قفل شدن حساب پس از ۵ تلاش ناموفق برای ورود
- محدودیت نرخ روی همه endpointهای حساس
- مدیریت Session با ردیابی هر دستگاه
- لاگ امنیتی برای همه رویدادهای احراز هویت
- محافظت CSRF از طریق کوکیهای SameSite
- حداکثر Session برای هر کاربر (قابل تنظیم)
- ورود خودکار در ثبتنام برای تجربه کاربری بهتر
- بازنشانی توکن بدون احراز هویت مجدد
- پشتیبانی از چند session با امکان ابطال جداگانه
- Swagger UI با مستندات خودکار
- Async SQLAlchemy با پشتیبانی از PostgreSQL/SQLite
- Alembic Migrations برای نسخهبندی دیتابیس
- Python 3.12+
- PostgreSQL (یا SQLite برای توسعه)
- Redis (اختیاری، برای محدودیت نرخ در production)
# کلون کردن مخزن
git clone https://github.com/moeinrezai/FastAPI-Authentication.git
cd fastapi-auth-system
# ایجاد محیط مجازی
python -m venv venv
source venv/bin/activate # در ویندوز: venv\Scripts\activate
# نصب وابستگیها
pip install -r requirements.txt
# تنظیم متغیرهای محیطی
cp .env.example .env
# .env را با تنظیمات خود ویرایش کنید
# اجرای migrations
python -m alembic upgrade head
# شروع سرور
fastapi devیک فایل .env ایجاد کنید:
# دیتابیس
DATABASE_URL=sqlite+aiosqlite:///./data/app.db
# JWT
SECRET_KEY=کلید-محرمانه-حداقل-۳۲-کاراکتر
JWT_ALGORITHM=HS256
ACCESS_TOKEN_EXPIRE_MINUTES=30
REFRESH_TOKEN_EXPIRE_DAYS=7
# امنیت کوکی
COOKIE_SECURE=false # در production روی true تنظیم کنید
COOKIE_SAMESITE=lax
# امنیت
MAX_SESSIONS_PER_USER=3
MAX_LOGIN_ATTEMPTS=5
LOCKOUT_DURATION_MINUTES=15
BCRYPT_ROUNDS=12
# محدودیت نرخ
RATE_LIMIT_REGISTER=5/minute
RATE_LIMIT_LOGIN=10/minute
RATE_LIMIT_REFRESH=20/minute
RATE_LIMIT_LOGOUT=20/minute
# محیط
ENVIRONMENT=development
DEBUG=trueپروژه شامل یک CLI جامع برای مدیریت کاربران است:
# ساخت کاربران
python -m app.scripts.cli create-user --email user@example.com
python -m app.scripts.cli create-admin --email admin@example.com
python -m app.scripts.cli create-manager --email manager@example.com
python -m app.scripts.cli create-support --email support@example.com
# مدیریت کاربران
python -m app.scripts.cli list-users
python -m app.scripts.cli change-role --email user@example.com --role admin
python -m app.scripts.cli reset-password --email user@example.com
python -m app.scripts.cli activate-user --email user@example.com
python -m app.scripts.cli deactivate-user --email user@example.com# اجرای همه تستها
python -m pytest -v
# اجرا همراه با coverage
python -m pytest -v --cov=app --cov-report=term-missing
# اجرای فایل تست احراز هویت
python -m pytest tests/test_auth.py -vآخرین نتیجه اجرای تست:
- ✅ ۱۰۶ تست موفق
⚠️ ۵ هشدار- ⏱️ زمان اجرا: ۷۰.۵۲ ثانیه
- 📊 پوشش کلی کد: ۶۴٪
- 🐍 Python 3.12.7
- 🧪 pytest 9.1.1
- 🔌 pytest-asyncio 1.4.0
- 📦 ۱۰۶ تست جمعآوری شد
- ❌ ۰ تست ناموفق
- ⏭️ ۰ تست Skip شده
| فایل تست | تعداد | نتیجه |
|---|---|---|
tests/test_admin.py |
۳۱ | ✅ ۳۱ موفق |
tests/test_auth.py |
۲۹ | ✅ ۲۹ موفق |
tests/test_sessions.py |
۱۰ | ✅ ۱۰ موفق |
tests/test_tickets.py |
۲۳ | ✅ ۲۳ موفق |
tests/test_users.py |
۱۳ | ✅ ۱۳ موفق |
| مجموع | ۱۰۶ | ✅ ۱۰۶ موفق |
| بخش | Coverage |
|---|---|
app/api/v1/endpoints/admin.py |
۶۸٪ |
app/api/v1/endpoints/auth.py |
۷۸٪ |
app/api/v1/endpoints/sessions.py |
۷۶٪ |
app/api/v1/endpoints/tickets.py |
۹۳٪ |
app/api/v1/endpoints/users.py |
۱۰۰٪ |
app/core/config.py |
۱۰۰٪ |
app/core/permissions.py |
۷۱٪ |
app/core/security.py |
۸۴٪ |
app/dependencies.py |
۷۸٪ |
app/main.py |
۹۳٪ |
app/models/session.py |
۹۵٪ |
app/models/ticket.py |
۱۰۰٪ |
app/models/ticket_reply.py |
۱۰۰٪ |
app/models/token.py |
۱۰۰٪ |
app/models/user.py |
۱۰۰٪ |
app/schemas/auth.py |
۹۶٪ |
app/schemas/session.py |
۱۰۰٪ |
app/schemas/ticket.py |
۱۰۰٪ |
app/schemas/user.py |
۱۰۰٪ |
app/services/auth_service.py |
۳۸٪ |
app/services/session_service.py |
۵۰٪ |
app/services/ticket_service.py |
۴۴٪ |
app/services/user_service.py |
۴۹٪ |
| مجموع | ۶۴٪ |
در اجرای ارائهشده، ۵ هشدار
DeprecationWarningمربوط به نحوه استفاده از Cookie در HTTPX ثبت شده است. این هشدارها باعث شکست هیچکدام از تستها نشدهاند.
نمایش خروجی دقیق pytest
(venv) PS D:\FastAPI Authentication\project> python -m pytest -v --cov=app --cov-report=term-missing
============================================================= test session starts =============================================================
platform win32 -- Python 3.12.7, pytest-9.1.1, pluggy-1.6.0 -- C:\Users\Npc\AppData\Local\Programs\Python\Python312\python.exe
cachedir: .pytest_cache
rootdir: D:\FastAPI Authentication\project
configfile: pytest.ini
plugins: anyio-4.14.1, Faker-40.36.0, asyncio-1.4.0, cov-4.1.0, django-4.7.0
asyncio: mode=Mode.STRICT, debug=False, asyncio_default_fixture_loop_scope=None, asyncio_default_test_loop_scope=function
collected 106 items
tests/test_admin.py::TestListUsers::test_list_users_as_admin PASSED [ 0%]
tests/test_admin.py::TestListUsers::test_list_users_as_manager PASSED [ 1%]
tests/test_admin.py::TestListUsers::test_list_users_as_regular_user PASSED [ 2%]
tests/test_admin.py::TestListUsers::test_list_users_as_support_fails PASSED [ 3%]
tests/test_admin.py::TestListUsers::test_list_users_unauthorized PASSED [ 4%]
tests/test_admin.py::TestListUsers::test_list_users_pagination PASSED [ 5%]
tests/test_admin.py::TestGetUser::test_get_user_as_admin PASSED [ 6%]
tests/test_admin.py::TestGetUser::test_get_user_as_manager PASSED [ 7%]
tests/test_admin.py::TestGetUser::test_get_user_as_regular_user PASSED [ 8%]
tests/test_admin.py::TestGetUser::test_get_user_not_found PASSED [ 9%]
tests/test_admin.py::TestUpdateUserStatus::test_deactivate_user PASSED [ 10%]
tests/test_admin.py::TestUpdateUserStatus::test_activate_user PASSED [ 11%]
tests/test_admin.py::TestUpdateUserStatus::test_deactivate_user_as_manager PASSED [ 12%]
tests/test_admin.py::TestUpdateUserStatus::test_deactivate_user_as_regular_user PASSED [ 13%]
tests/test_admin.py::TestChangeUserRole::test_change_role_as_admin PASSED [ 14%]
tests/test_admin.py::TestChangeUserRole::test_change_role_as_manager_fails PASSED [ 15%]
tests/test_admin.py::TestChangeUserRole::test_change_role_as_regular_user_fails PASSED [ 16%]
tests/test_admin.py::TestChangeUserRole::test_change_role_invalid_role PASSED [ 16%]
tests/test_admin.py::TestCreateUserByAdmin::test_create_user_as_admin PASSED [ 17%]
tests/test_admin.py::TestCreateUserByAdmin::test_create_user_as_manager_fails PASSED [ 18%]
tests/test_admin.py::TestCreateUserByAdmin::test_create_user_duplicate_email PASSED [ 19%]
tests/test_admin.py::TestDeleteUser::test_delete_user_as_admin PASSED [ 20%]
tests/test_admin.py::TestDeleteUser::test_delete_user_as_manager_fails PASSED [ 21%]
tests/test_admin.py::TestDeleteUser::test_delete_user_as_regular_user PASSED [ 22%]
tests/test_admin.py::TestDeleteUser::test_delete_self_fails PASSED [ 23%]
tests/test_admin.py::TestAdminLogs::test_get_logs_as_admin PASSED [ 24%]
tests/test_admin.py::TestAdminLogs::test_get_logs_as_manager PASSED [ 25%]
tests/test_admin.py::TestAdminLogs::test_get_logs_as_regular_user PASSED [ 26%]
tests/test_admin.py::TestAdminLogs::test_get_logs_as_support_fails PASSED [ 27%]
tests/test_admin.py::TestAdminLogs::test_get_logs_pagination PASSED [ 28%]
tests/test_admin.py::TestAdminLogs::test_logs_contain_login_events PASSED [ 29%]
tests/test_auth.py::TestRegister::test_register_success PASSED [ 30%]
tests/test_auth.py::TestRegister::test_register_duplicate_email PASSED [ 31%]
tests/test_auth.py::TestRegister::test_register_password_mismatch PASSED [ 32%]
tests/test_auth.py::TestRegister::test_register_weak_password_too_short PASSED [ 33%]
tests/test_auth.py::TestRegister::test_register_weak_password_no_uppercase PASSED [ 33%]
tests/test_auth.py::TestRegister::test_register_weak_password_no_lowercase PASSED [ 34%]
tests/test_auth.py::TestRegister::test_register_weak_password_no_digit PASSED [ 35%]
tests/test_auth.py::TestRegister::test_register_weak_password_no_special_char PASSED [ 36%]
tests/test_auth.py::TestRegister::test_register_invalid_email PASSED [ 37%]
tests/test_auth.py::TestLogin::test_login_success PASSED [ 38%]
tests/test_auth.py::TestLogin::test_login_wrong_password PASSED [ 39%]
tests/test_auth.py::TestLogin::test_login_nonexistent_user PASSED [ 40%]
tests/test_auth.py::TestLogin::test_login_empty_password PASSED [ 41%]
tests/test_auth.py::TestLogin::test_login_short_email PASSED [ 42%]
tests/test_auth.py::TestLogin::test_login_invalid_email_format PASSED [ 43%]
tests/test_auth.py::TestRefresh::test_refresh_success PASSED [ 44%]
tests/test_auth.py::TestRefresh::test_refresh_missing_cookie PASSED [ 45%]
tests/test_auth.py::TestRefresh::test_refresh_invalid_token PASSED [ 46%]
tests/test_auth.py::TestRefresh::test_refresh_token_reuse_detection PASSED [ 47%]
tests/test_auth.py::TestLogout::test_logout_success PASSED [ 48%]
tests/test_auth.py::TestLogout::test_logout_without_cookie PASSED [ 49%]
tests/test_auth.py::TestLogout::test_logout_all_success PASSED [ 50%]
tests/test_auth.py::TestPasswordChange::test_change_password_success PASSED [ 50%]
tests/test_auth.py::TestPasswordChange::test_change_password_wrong_old PASSED [ 51%]
tests/test_auth.py::TestPasswordChange::test_change_password_same_as_old PASSED [ 52%]
tests/test_auth.py::TestPasswordChange::test_change_password_mismatch PASSED [ 53%]
tests/test_auth.py::TestPasswordChange::test_change_password_weak_new PASSED [ 54%]
tests/test_auth.py::TestPasswordChange::test_change_password_unauthorized PASSED [ 55%]
tests/test_auth.py::TestHealth::test_health_check PASSED [ 56%]
tests/test_sessions.py::TestListSessions::test_list_sessions_success PASSED [ 57%]
tests/test_sessions.py::TestListSessions::test_list_sessions_contains_current PASSED [ 58%]
tests/test_sessions.py::TestListSessions::test_list_sessions_unauthorized PASSED [ 59%]
tests/test_sessions.py::TestListSessions::test_list_sessions_invalid_token PASSED [ 60%]
tests/test_sessions.py::TestListSessions::test_list_sessions_empty_for_new_user PASSED [ 61%]
tests/test_sessions.py::TestListSessions::test_multiple_sessions PASSED [ 62%]
tests/test_sessions.py::TestRevokeSession::test_revoke_current_session_fails PASSED [ 63%]
tests/test_sessions.py::TestRevokeSession::test_revoke_nonexistent_session PASSED [ 64%]
tests/test_sessions.py::TestRevokeSession::test_revoke_session_unauthorized PASSED [ 65%]
tests/test_sessions.py::TestRevokeSession::test_revoke_other_users_session_fails PASSED [ 66%]
tests/test_tickets.py::TestCreateTicket::test_create_ticket_success PASSED [ 66%]
tests/test_tickets.py::TestCreateTicket::test_create_ticket_unauthorized PASSED [ 67%]
tests/test_tickets.py::TestCreateTicket::test_create_ticket_subject_too_short PASSED [ 68%]
tests/test_tickets.py::TestCreateTicket::test_create_ticket_description_too_short PASSED [ 69%]
tests/test_tickets.py::TestCreateTicket::test_create_ticket_support_role_fails PASSED [ 70%]
tests/test_tickets.py::TestListTickets::test_list_tickets_as_user PASSED [ 71%]
tests/test_tickets.py::TestListTickets::test_list_tickets_only_own PASSED [ 72%]
tests/test_tickets.py::TestListTickets::test_list_tickets_as_support_sees_all PASSED [ 73%]
tests/test_tickets.py::TestListTickets::test_list_tickets_unauthorized PASSED [ 74%]
tests/test_tickets.py::TestGetTicket::test_get_ticket_as_owner PASSED [ 75%]
tests/test_tickets.py::TestGetTicket::test_get_ticket_as_other_user_fails PASSED [ 76%]
tests/test_tickets.py::TestGetTicket::test_get_ticket_as_support PASSED [ 77%]
tests/test_tickets.py::TestGetTicket::test_get_ticket_not_found PASSED [ 78%]
tests/test_tickets.py::TestReplyToTicket::test_reply_as_owner PASSED [ 79%]
tests/test_tickets.py::TestReplyToTicket::test_reply_as_support_updates_status PASSED [ 80%]
tests/test_tickets.py::TestReplyToTicket::test_reply_as_other_user_fails PASSED [ 81%]
tests/test_tickets.py::TestReplyToTicket::test_reply_empty_message_fails PASSED [ 82%]
tests/test_tickets.py::TestReplyToTicket::test_reply_nonexistent_ticket PASSED [ 83%]
tests/test_tickets.py::TestDeleteTicket::test_delete_ticket_as_admin PASSED [ 83%]
tests/test_tickets.py::TestDeleteTicket::test_delete_ticket_as_manager PASSED [ 84%]
tests/test_tickets.py::TestDeleteTicket::test_delete_ticket_as_support_fails PASSED [ 85%]
tests/test_tickets.py::TestDeleteTicket::test_delete_ticket_as_regular_user_fails PASSED [ 86%]
tests/test_tickets.py::TestDeleteTicket::test_delete_ticket_not_found PASSED [ 87%]
tests/test_users.py::TestGetProfile::test_get_profile_success PASSED [ 88%]
tests/test_users.py::TestGetProfile::test_get_profile_unauthorized PASSED [ 89%]
tests/test_users.py::TestGetProfile::test_get_profile_invalid_token PASSED [ 90%]
tests/test_users.py::TestGetProfile::test_get_profile_refresh_token_as_bearer PASSED [ 91%]
tests/test_users.py::TestUpdateProfile::test_update_username PASSED [ 92%]
tests/test_users.py::TestUpdateProfile::test_update_email PASSED [ 93%]
tests/test_users.py::TestUpdateProfile::test_update_both PASSED [ 94%]
tests/test_users.py::TestUpdateProfile::test_update_email_duplicate PASSED [ 95%]
tests/test_users.py::TestUpdateProfile::test_update_username_duplicate PASSED [ 96%]
tests/test_users.py::TestUpdateProfile::test_update_invalid_email PASSED [ 97%]
tests/test_users.py::TestUpdateProfile::test_update_invalid_username PASSED [ 98%]
tests/test_users.py::TestUpdateProfile::test_update_username_too_short PASSED [ 99%]
tests/test_users.py::TestUpdateProfile::test_update_unauthorized PASSED [100%]
============================================================== warnings summary ===============================================================
tests/test_auth.py::TestRefresh::test_refresh_success
tests/test_auth.py::TestRefresh::test_refresh_invalid_token
tests/test_auth.py::TestRefresh::test_refresh_token_reuse_detection
tests/test_auth.py::TestRefresh::test_refresh_token_reuse_detection
tests/test_auth.py::TestLogout::test_logout_success
C:\Users\Npc\AppData\Local\Programs\Python\Python312\Lib\site-packages\httpx\_client.py:1859: DeprecationWarning: Setting per-request cookies=<...> is being deprecated, because the expected behaviour on cookie persistence is ambiguous. Set cookies directly on the client instance instead.
return await self.request(
-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
---------- coverage: platform win32, python 3.12.7-final-0 -----------
Name Stmts Miss Cover Missing
----------------------------------------------------------------
app\__init__.py 0 0 100%
app\api\__init__.py 0 0 100%
app\api\v1\__init__.py 0 0 100%
app\api\v1\endpoints\__init__.py 2 0 100%
app\api\v1\endpoints\admin.py 62 20 68% 49-72, 86, 109, 124-127, 141-142, 162-163
app\api\v1\endpoints\auth.py 85 19 78% 85, 109-118, 140-146, 174-180, 220-224, 245-249
app\api\v1\endpoints\sessions.py 25 6 76% 38-44, 62
app\api\v1\endpoints\tickets.py 30 2 93% 54, 89
app\api\v1\endpoints\users.py 15 0 100%
app\core\__init__.py 5 0 100%
app\core\config.py 30 0 100%
app\core\permissions.py 14 4 71% 66, 70, 74, 78
app\core\rate_limit.py 3 0 100%
app\core\security.py 49 8 84% 23-24, 100-112
app\db\__init__.py 3 0 100%
app\db\base.py 3 0 100%
app\db\session.py 10 4 60% 20-24
app\dependencies.py 80 18 78% 30, 65-85, 92, 134, 138, 142, 150, 159, 163
app\main.py 27 2 93% 18-19
app\models\__init__.py 7 0 100%
app\models\log.py 13 0 100%
app\models\session.py 21 1 95% 15
app\models\ticket.py 21 0 100%
app\models\ticket_reply.py 14 0 100%
app\models\ticket_status.py 5 5 0% 1-7
app\models\token.py 10 0 100%
app\models\user.py 21 0 100%
app\models\user_role.py 6 0 100%
app\schemas\__init__.py 5 0 100%
app\schemas\auth.py 57 2 96% 8, 10
app\schemas\session.py 15 0 100%
app\schemas\ticket.py 30 0 100%
app\schemas\user.py 25 0 100%
app\scripts\__init__.py 0 0 100%
app\scripts\cli.py 161 161 0% 15-243
app\services\__init__.py 5 0 100%
app\services\auth_service.py 157 97 38% 33, 62-88, 93-94, 103-106, 116-121, 132-158, 169-198, 221-289, 300, 305-310, 322-326, 346-354
app\services\session_service.py 24 12 50% 23, 33, 44-63
app\services\ticket_service.py 50 28 44% 23-24, 36, 48-63, 70-97, 102-111
app\services\user_service.py 49 25 49% 14-20, 31-37, 41-51, 60-65, 71-72, 85-90
----------------------------------------------------------------
TOTAL 1139 414 64%
================================================= 106 passed, 5 warnings in 70.52s (0:01:10) ==================================================
(venv) PS D:\FastAPI Authentication\project>
POST /api/v1/auth/register- ثبتنام کاربر (ورود خودکار)POST /api/v1/auth/login- ورود کاربرPOST /api/v1/auth/refresh- بازنشانی access tokenPOST /api/v1/auth/logout- خروج از session فعلیPOST /api/v1/auth/logout-all- خروج از همه sessionهاPUT /api/v1/auth/password- تغییر رمز عبور
GET /api/v1/users/me- دریافت پروفایل کاربر فعلیPUT /api/v1/users/me- بهروزرسانی پروفایل
GET /api/v1/sessions- لیست sessionهای فعالDELETE /api/v1/sessions/{id}- ابطال session خاص
GET /api/v1/admin/users- لیست همه کاربرانPOST /api/v1/admin/users- ساخت کاربر (فقط Admin)GET /api/v1/admin/users/{id}- دریافت جزئیات کاربرPATCH /api/v1/admin/users/{id}/status- فعال/غیرفعال کردن کاربرPATCH /api/v1/admin/users/{id}/role- تغییر نقش کاربر (فقط Admin)DELETE /api/v1/admin/users/{id}- حذف کاربر (فقط Admin)GET /api/v1/admin/logs- مشاهده لاگهای امنیتی
POST /api/v1/tickets- ساخت تیکتGET /api/v1/tickets- لیست تیکتهاGET /api/v1/tickets/{id}- دریافت جزئیات تیکتPOST /api/v1/tickets/{id}/reply- پاسخ به تیکتDELETE /api/v1/tickets/{id}- حذف تیکت (Admin/Manager)
تصاویر زیر جریانهای اصلی احراز هویت، Session، کاربر، تیکت و خروج از حساب را در Swagger UI نمایش میدهند.
تصاویر را با نامهای زیر داخل مسیر
docs/screenshots/قرار دهید. مسیر تصاویر در همین README تنظیم شده است.
| بخش | فایل تصویر |
|---|---|
| ثبتنام | docs/screenshots/01-register.png |
| ورود | docs/screenshots/02-login.png |
| Sessionها | docs/screenshots/03-sessions.png |
| کاربر فعلی | docs/screenshots/04-user.png |
| ایجاد تیکت | docs/screenshots/05-ticket-create.png |
| پاسخ به تیکت | docs/screenshots/06-ticket-reply.png |
| خروج | docs/screenshots/07-logout.png |
project/
├── app/
│ ├── api/v1/endpoints/ # هندلرهای route API
│ ├── core/ # ماژولهای اصلی (config, security, permissions)
│ ├── db/ # مدلهای دیتابیس و session
│ ├── models/ # مدلهای SQLAlchemy
│ ├── schemas/ # اسکیمای Pydantic
│ ├── scripts/ # اسکریپتهای CLI
│ ├── services/ # منطق تجاری
│ └── main.py # اپلیکیشن FastAPI
├── tests/ # فایلهای تست
├── docs/
│ └── screenshots/ # تصاویر Swagger UI
├── alembic/ # Migrationهای دیتابیس
├── data/ # دیتابیس SQLite (dev)
├── requirements.txt # وابستگیهای Python
├── pytest.ini # پیکربندی Pytest
└── .env # متغیرهای محیطی
۱. امنیت رمز عبور
- هش Bcrypt با ۱۲ دور
- اعتبارسنجی قدرت رمز عبور
- عدم وجود رمز عبور در توکنهای JWT
۲. امنیت توکن
- توکنهای access کوتاهمدت (۳۰ دقیقه)
- توکنهای refresh بلندمدت (۷ روز)
- چرخش توکن در هنگام refresh
- ابطال مبتنی بر family برای تشخیص استفاده مجدد
۳. امنیت Session
- اثر انگشت دستگاه
- حداکثر session برای هر کاربر
- ابطال جداگانه session
- انقضای session
۴. امنیت کوکی
- پرچم HttpOnly (بدون دسترسی JavaScript)
- پرچم Secure (فقط HTTPS در production)
- ویژگی SameSite (محافظت CSRF)
- محدودیت مسیر
۵. محدودیت نرخ
- محدودیت نرخ برای هر endpoint
- محدودیتهای قابل تنظیم
- ردیابی مبتنی بر IP
- معماری Async: همه عملیات دیتابیس async هستند
- Connection Pooling: Connection pooling SQLAlchemy فعال است
- بهینهسازی Query: کوئریهای کارآمد با ایندکسگذاری مناسب
- آماده Caching: اضافه کردن لایه caching Redis آسان است
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["fastapi", "run", "app/main.py", "--host", "0.0.0.0", "--port", "8000"]ENVIRONMENT=production
DEBUG=false
COOKIE_SECURE=true
COOKIE_SAMESITE=strict
DATABASE_URL=postgresql+asyncpg://user:pass@host:5432/db- Swagger UI: http://localhost:8000/docs
- ReDoc: http://localhost:8000/redoc
- OpenAPI JSON: http://localhost:8000/openapi.json
Moein Rezaie / معین رضایی
- 📧 Email: moeinrezaie516@gmail.com
- 💬 Telegram: @moein9401
- 💼 LinkedIn: moein-rezaie1997
- 🐙 GitHub: moeinrezai
This project is licensed under the MIT License - see the LICENSE file for details.
این پروژه تحت مجوز MIT منتشر شده است - برای جزئیات به فایل LICENSE مراجعه کنید.
Contributions are welcome! Please feel free to submit a Pull Request.
مشارکتها مورد استقبال است! لطفاً در ارسال Pull Request تردید نکنید.
Give a ⭐️ if this project helped you!
اگر این پروژه به شما کمک کرد، یک ⭐️ بدهید!
Made with ❤️ by Moein Rezaie












