Skip to content

About

A secure and production-oriented FastAPI authentication system with JWT, RBAC, session management, HttpOnly cookies, token rotation, device fingerprinting, and security features.

Topics

Resources

Stars

15 stars

Watchers

0 watching

Forks

Latest commit

 

History

56 Commits

Folders and files

Repository files navigation

🔐 FastAPI Authentication System

سیستم احراز هویت پیشرفته FastAPI

A Production-Grade JWT Authentication System with RBAC, Session Management, and Security Features

Python 3.12 FastAPI Tests Coverage License


English | فارسی


English

🌟 Overview

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.

✨ Key Features

🔐 Authentication & Authorization

  • 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 access
    • SUPPORT: Ticket management
    • MANAGER: User management + logs
    • ADMIN: Full system access

🛡️ Security Features

  • 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)

🎯 API Features

  • 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

🚀 Quick Start

Prerequisites

  • Python 3.12+
  • PostgreSQL (or SQLite for development)
  • Redis (optional, for production rate limiting)

Installation

# 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 dev

Environment Variables

Create 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=true

📖 CLI Commands

The 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

🧪 Testing

# 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 -v

Latest 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 Suite Breakdown

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

Coverage

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 DeprecationWarning warnings 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>

📊 API Endpoints

Authentication

  • POST /api/v1/auth/register - User registration (auto-login)
  • POST /api/v1/auth/login - User login
  • POST /api/v1/auth/refresh - Refresh access token
  • POST /api/v1/auth/logout - Logout current session
  • POST /api/v1/auth/logout-all - Logout all sessions
  • PUT /api/v1/auth/password - Change password

Users

  • GET /api/v1/users/me - Get current user profile
  • PUT /api/v1/users/me - Update profile

Sessions

  • GET /api/v1/sessions - List active sessions
  • DELETE /api/v1/sessions/{id} - Revoke specific session

Admin (requires appropriate role)

  • GET /api/v1/admin/users - List all users
  • POST /api/v1/admin/users - Create user (Admin only)
  • GET /api/v1/admin/users/{id} - Get user details
  • PATCH /api/v1/admin/users/{id}/status - Activate/deactivate user
  • PATCH /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

Tickets

  • POST /api/v1/tickets - Create ticket
  • GET /api/v1/tickets - List tickets
  • GET /api/v1/tickets/{id} - Get ticket details
  • POST /api/v1/tickets/{id}/reply - Reply to ticket
  • DELETE /api/v1/tickets/{id} - Delete ticket (Admin/Manager)

📸 Swagger UI Screenshots

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

Register

Swagger UI - Register Swagger UI - Register

Login

Swagger UI - Login Swagger UI - Login

Sessions

Swagger UI - Sessions

Current User

Swagger UI - Current User

Create Ticket

Swagger UI - Create Ticket Swagger UI - Create Ticket

Reply to Ticket

Swagger UI - Reply to Ticket Swagger UI - Reply to Ticket

All Tickets and Reply by user

Swagger UI - Reply to Ticket

Logout

Swagger UI - Logout

For the complete screenshot checklist and recommended order, see docs/SWAGGER.md.

🏗️ Project Structure

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                  

🔒 Security Best Practices Implemented

  1. Password Security

    • Bcrypt hashing with 12 rounds
    • Password strength validation
    • No passwords in JWT tokens
  2. Token Security

    • Short-lived access tokens (30 min)
    • Long-lived refresh tokens (7 days)
    • Token rotation on refresh
    • Family-based revocation for reuse detection
  3. Session Security

    • Device fingerprinting
    • Maximum sessions per user
    • Individual session revocation
    • Session expiration
  4. Cookie Security

    • HttpOnly flag (no JavaScript access)
    • Secure flag (HTTPS only in production)
    • SameSite attribute (CSRF protection)
    • Path restriction
  5. Rate Limiting

    • Per-endpoint rate limits
    • Configurable limits
    • IP-based tracking

📈 Performance

  • 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

🚢 Deployment

Docker (Recommended)

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 for Production

ENVIRONMENT=production
DEBUG=false
COOKIE_SECURE=true
COOKIE_SAMESITE=strict
DATABASE_URL=postgresql+asyncpg://user:pass@host:5432/db

📚 Documentation


فارسی

🌟 معرفی

یک سیستم احراز هویت جامع و آماده برای محیط 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 برای هر کاربر (قابل تنظیم)

🎯 ویژگی‌های API

  • ورود خودکار در ثبت‌نام برای تجربه کاربری بهتر
  • بازنشانی توکن بدون احراز هویت مجدد
  • پشتیبانی از چند 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

پروژه شامل یک 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 شده

تفکیک Test Suiteها

فایل تست تعداد نتیجه
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>

📊 Endpointهای API

احراز هویت

  • POST /api/v1/auth/register - ثبت‌نام کاربر (ورود خودکار)
  • POST /api/v1/auth/login - ورود کاربر
  • POST /api/v1/auth/refresh - بازنشانی access token
  • POST /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 - به‌روزرسانی پروفایل

Sessionها

  • 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)

📸 تصاویر عملکرد Swagger UI

تصاویر زیر جریان‌های اصلی احراز هویت، 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

ثبت‌نام

Swagger UI - Register

ورود

Swagger UI - Login

Sessionها

Swagger UI - Sessions

کاربر فعلی

Swagger UI - Current User

ایجاد تیکت

Swagger UI - Create Ticket

پاسخ به تیکت

Swagger UI - Reply to Ticket

خروج

Swagger UI - Logout

🏗️ ساختار پروژه

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 آسان است

🚢 استقرار

Docker (توصیه شده)

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"]

محیط برای Production

ENVIRONMENT=production
DEBUG=false
COOKIE_SECURE=true
COOKIE_SAMESITE=strict
DATABASE_URL=postgresql+asyncpg://user:pass@host:5432/db

📚 مستندات


👨‍💻 Developer / توسعه‌دهنده

Moein Rezaie / معین رضایی


📄 License / مجوز

This project is licensed under the MIT License - see the LICENSE file for details.

این پروژه تحت مجوز MIT منتشر شده است - برای جزئیات به فایل LICENSE مراجعه کنید.


🤝 Contributing / مشارکت

Contributions are welcome! Please feel free to submit a Pull Request.

مشارکت‌ها مورد استقبال است! لطفاً در ارسال Pull Request تردید نکنید.


⭐ Show your support / حمایت خود را نشان دهید

Give a ⭐️ if this project helped you!

اگر این پروژه به شما کمک کرد، یک ⭐️ بدهید!


Made with ❤️ by Moein Rezaie

About

A secure and production-oriented FastAPI authentication system with JWT, RBAC, session management, HttpOnly cookies, token rotation, device fingerprinting, and security features.

Topics

Resources

Stars

15 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages