فصل ۱۹ — بهینه‌سازی و امنیت در Django

""

۱. مقدمه — چرا امنیت و بهینه‌سازی مهم است؟

در هر وب‌سایت یا API، دو چالش اصلی داریم:

  1. امنیت → جلوگیری از نفوذ، سرقت داده یا تغییر غیرمجاز.
  2. بهینه‌سازی (Performance) → افزایش سرعت و کاهش مصرف منابع سرور.

مشکل رایج در پروژه‌های واقعی:

  • هکرها حملات XSS, CSRF, SQL Injection انجام می‌دهند.
  • سایت کند می‌شود به دلیل کوئری‌های سنگین یا استفاده زیاد از دیتابیس.
  • منابع (CPU, RAM) بیخود مصرف می‌شوند چون هیچ Caching یا فایل استاتیک بهینه‌ای استفاده نشده.

۲. اصول امنیت در Django

جنگو خودش خیلی از موارد امنیتی رو پیش‌فرض فعال کرده، مثل:

  • جلوگیری از SQL Injection (از طریق ORM)
  • جلوگیری از CSRF (با Middleware داخلی)
  • رمزنگاری رمز عبور کاربر

اما باید این نکات رو رعایت کنیم:


۲.۱ جلوگیری از SQL Injection

ORM جنگو ذاتاً امنه ولی اگه از Raw SQL استفاده کنیم، باید همیشه پارامترها رو ایمن کنیم.

مثال اشتباه:

# خطرناک!
Product.objects.raw(f"SELECT * FROM store_product WHERE id={product_id}")

روش امن:

Product.objects.raw("SELECT * FROM store_product WHERE id = %s", [product_id])

📌 بهترین حالت: از ORM استفاده کن:

product = Product.objects.get(id=product_id)

۲.۲ جلوگیری از XSS (Cross-Site Scripting)

XSS یعنی تزریق کد جاوااسکریپت توسط کاربر و اجرای آن در مرورگر دیگران.

جنگو به صورت پیش‌فرض داده‌ها رو در قالب HTML escape می‌کنه:

{{ user_input }}

ولی اگر |safe استفاده کنی، مراقب باش فقط روی داده‌های مطمئن باشه:

{{ trusted_content|safe }}

۲.۳ جلوگیری از CSRF (Cross-Site Request Forgery)

CSRF یعنی درخواست جعلی از طرف کاربر بدون اطلاعش.

در جنگو برای هر فرم:

<form method="post">
    {% csrf_token %}
    <!-- فیلدها -->
</form>

📌 برای APIها باید از CSRF exemption یا روش‌های امن دیگر مثل Token Auth استفاده کنیم.


۲.۴ مدیریت رمز عبور

رمزها باید هش شده ذخیره شوند (جنگو این کار رو با PBKDF2 + SHA256 انجام میده).

وقتی کاربر رمز وارد می‌کنه:

from django.contrib.auth.hashers import make_password

user.password = make_password(raw_password)

📌 هرگز رمز رو در متن ساده ذخیره نکن.


۲.۵ محدود کردن تعداد تلاش (Login Attempt)

برای جلوگیری از Brute Force Attack می‌توانیم از کتابخانه‌هایی مثل:

pip install django-axes

این کتابخانه بعد از چند تلاش ناموفق کاربر رو بلاک می‌کنه.


۳. اصول بهینه‌سازی در Django

بهینه‌سازی یعنی کم کردن حجم پردازش و تعداد درخواست‌ها تا سرعت سایت زیاد بشه.


۳.۱ استفاده از Query بهینه

اشتباه رایج:

for order in Order.objects.all():
    print(order.customer.name)  # باعث 1 کوئری برای هر سفارش میشه!

🔴 این همون مشکل N+1 Query هست.

روش بهینه با select_related:

orders = Order.objects.select_related('customer').all()
for order in orders:
    print(order.customer.name)

برای ManyToMany یا ForeignKey معکوس:

products = Product.objects.prefetch_related('categories').all()

۳.۲ استفاده از Cache

کش کردن نتایج برای جلوگیری از فراخوانی مکرر دیتابیس.

در settings.py:

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
        'LOCATION': 'unique-snowflake'
    }
}

در views.py:

from django.core.cache import cache

def get_featured_products():
    products = cache.get('featured_products')
    if not products:
        products = Product.objects.filter(featured=True)
        cache.set('featured_products', products, 3600)  # یک ساعت
    return products

📌 می‌توان از Redis یا Memcached برای کش قوی‌تر استفاده کرد.


۳.۳ استفاده از فایل‌های استاتیک بهینه

  • استفاده از Collectstatic برای جمع کردن فایل‌ها
  • فشرده‌سازی CSS و JS با ابزارهایی مثل django-compressor
  • استفاده از CDN برای ارسال تصاویر و فایل‌ها به کاربر

۳.۴ Pagination در داده‌ها

هرگز کل داده‌ها رو یکجا نده، از صفحه‌بندی استفاده کن (مثل فصل ۱۳).


۳.۵ استفاده از Background Tasks

کارهای سنگین رو در پس‌زمینه انجام بده:

  • ارسال ایمیل
  • پردازش تصویر
  • گرفتن داده از API

📌 ابزار محبوب: Celery + Redis


۴. امنیت APIها

اگر پروژه شما API هم دارد:

  • استفاده از احراز هویت امن (Token/JWT/OAuth2)
  • محدود کردن درخواست‌ها (Throttling)
# settings.py
REST_FRAMEWORK = {
    'DEFAULT_THROTTLE_CLASSES': [
        'rest_framework.throttling.UserRateThrottle',
    ],
    'DEFAULT_THROTTLE_RATES': {
        'user': '100/day'
    }
}
  • بررسی ورودی‌ها قبل از ذخیره در دیتابیس

۵. جلوگیری از حملات رایج

حملهتوضیح کوتاهراه‌حل در Django
SQL Injectionتزریق کد SQLاستفاده از ORM
XSSتزریق کد جاوااسکریپتاستفاده از escape پیش‌فرض
CSRFدرخواست جعلیCSRF Token
Brute Forceتست مکرر رمز عبورمحدود کردن تلاش‌ها
Clickjackingفریب کاربر برای کلیکاضافه کردن HTTP Header X-Frame-Options

اضافه کردن هدر Clickjacking:

MIDDLEWARE += ['django.middleware.clickjacking.XFrameOptionsMiddleware']
X_FRAME_OPTIONS = 'DENY'

۶. امن‌سازی تنظیمات (settings.py)

  • DEBUG=False در محیط واقعی
  • نگهداری SECRET_KEY در .env
  • محدود کردن ALLOWED_HOSTS:
ALLOWED_HOSTS = ['yourdomain.com']
  • فعال کردن HTTPS (با HSTS):
SECURE_HSTS_SECONDS = 31536000
SECURE_SSL_REDIRECT = True

۷. مانیتورینگ و لاگ‌ها

برای رصد مشکلات و حملات:

LOGGING = {
    'version': 1,
    'handlers': {
        'file': {
            'level': 'ERROR',
            'class': 'logging.FileHandler',
            'filename': 'errors.log',
        },
    },
    'loggers': {
        'django': {
            'handlers': ['file'],
            'level': 'ERROR',
            'propagate': True,
        },
    },
}

📌 همیشه لاگ‌ها رو چک کن تا بفهمی کجا مشکل یا حمله رخ داده.


۸. بهینه‌سازی پرس و جوهای سنگین با Cache Template

اگر بخشی از صفحه همیشه تغییری نداره، می‌تونی کشش کنی:

{% load cache %}
{% cache 600 featured_products %}
    {% for product in products %}
        {{ product.name }}
    {% endfor %}
{% endcache %}

📌 اینجا ۶۰۰ ثانیه کش میشه.


۹. سناریوی واقعی — فروشگاه آنلاین امن و سریع

مراحل:

  1. فیلتر کردن همه ورودی‌ها (Form Validation)
  2. استفاده از ORM به جای Raw Query
  3. افزودن CSRF Token به فرم‌ها
  4. فعال‌سازی HTTPS و محدود کردن ALLOWED_HOSTS
  5. اضافه کردن Cache برای محصولات پرفروش
  6. استفاده از Pagination برای لیست طولانی محصولات
  7. استفاده از Celery برای کارهای سنگین (ایمیل، پردازش تصویر)
  8. محدود کردن تلاش ورود با django-axes
  9. بررسی مرتب لاگ‌ها برای کشف حملات

۱۰. نتیجه‌گیری فصل ۱۹

الان یاد گرفتیم چطور:

  • از حملات رایج مثل XSS و SQL Injection جلوگیری کنیم
  • سرعت سایت رو با Cache، Query بهینه، و Background Tasks بالا ببریم
  • تنظیمات امنیتی رو در محیط واقعی درست انجام بدیم
  • API رو ایمن کنیم
محمد وب‌سایت

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *