microdot.csrf --- حماية CSRF

يرفض الطلبات المُغيّرة للحالة التي تنشأ من مواقع أخرى (cross-site). يعمل الفحص كخطاف before_request ويستخدم ترويسة Sec-Fetch-Site التي يوفرها المتصفح (مع ترويسة Origin كبديل احتياطي للمتصفحات الأقدم، عند اقترانها بنسخة microdot.cors.CORS).

class CSRF

class microdot.csrf.CSRF(app: Microdot | None = None, cors=None, protect_all: bool = True, allow_subdomains: bool = False)
app

نسخة microdot.Microdot المراد التثبيت عليها. اختياري؛ استدعِ initialize() لاحقاً إذا لم تُعطَ.

cors

نسخة microdot.cors.CORS التي تحدد المصادر الموثوقة للتطبيق. مطلوبة للرجوع احتياطياً إلى ترويسة Origin على المتصفحات التي لا ترسل Sec-Fetch-Site. اختيارية؛ بدونها ينطبق فحص Sec-Fetch-Site فقط.

protect_all

إذا كانت True (الافتراضي)، يُحمى تلقائياً كل مسار باستثناء GET و HEAD و OPTIONS. يمكن إعفاء المسارات فردياً بـ exempt(). وإذا كانت False، لا يُحمى أي مسار افتراضياً وتختار المسارات الفردية الانضمام بـ protect().

allow_subdomains

إذا كانت True، تُقبل الطلبات الواردة من النطاقات الفرعية لمصادر التطبيق (same-site لـ Sec-Fetch-Site، أو لاحقة مصدر مطابقة).

initialize(app: Microdot, cors=None)

الربط بـ app إذا كان البناء قد أُجِّل.

exempt(f)

مزخرف يُعفي مساراً من حماية CSRF. ضعه مباشرة بعد مزخرف المسار:

@app.post('/webhook')
@csrf.exempt
async def webhook(request):
    # accepts cross-site POSTs
protect(f)

مزخرف يفرض حماية CSRF على مسار كان سيُعفى لولا ذلك (مثل مسار GET أو كل مسار عندما protect_all=False).

SAFE_METHODS: list

سمة صنف تسرد الطرق غير المحمية افتراضياً -- ['GET', 'HEAD', 'OPTIONS'].

مثال:

from microdot import Microdot
from microdot.cors import CORS
from microdot.csrf import CSRF

app = Microdot()
cors = CORS(app, allowed_origins=['https://app.example.com'])
csrf = CSRF(app, cors=cors)

@app.post('/api/save')
async def save(request):
    # automatically CSRF-protected
    return {'ok': True}

يُسمح بالطلب عندما يُبلِّغ Sec-Fetch-Site عن same-origin أو none (أو same-site عندما allow_subdomains=True). إذا كانت الترويسة غائبة، تُطابَق Origin الخاصة بالطلب مع قائمة السماح في CORS. تُقبل الطلبات التي تخلو من كلتا الترويستين (وهو أمر معتاد لاستدعاءات API المباشرة التي لا تخضع لـ CSRF في المتصفح).