microdot.csrf --- การป้องกัน CSRF¶
ปฏิเสธคำขอที่เปลี่ยนแปลงสถานะซึ่งมาจากต้นทางข้ามไซต์ การตรวจสอบทำงานเป็น hook 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-siteSec-Fetch-Site หรือ suffix ต้นทางที่ตรงกัน)
- exempt(f)¶
ตัวตกแต่งที่ยกเว้นเส้นทางจากการป้องกัน CSRF วางไว้หลังตัวตกแต่งเส้นทางโดยตรง:
@app.post('/webhook') @csrf.exempt async def webhook(request): # accepts cross-site POSTs
- protect(f)¶
ตัวตกแต่งที่บังคับการป้องกัน CSRF บนเส้นทางที่มิฉะนั้นจะได้รับการยกเว้น (เช่น เส้นทาง
GETหรือทุกเส้นทางเมื่อprotect_all=False)
ตัวอย่าง:
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 ของเบราว์เซอร์)