Package: fastapi-csrf-protect
FastAPI CSRF ProtectFeaturesFastAPI extension that provides stateless Cross-Site Request Forgery (XSRF) Protection support.
Aimed to be easy to use and lightweight, we adoptDouble Submit Cookiemitigation pattern.
If you were familiar withflask-wtflibrary this extension suitable for you.
This extension inspired byfastapi-jwt-auth😀Storingfastapi-csrf-tokenin cookies or serve it in template's contextInstallationThe easiest way to start working with this extension with pippipinstallfastapi-csrf-protect# orpoetryaddfastapi-csrf-protectGetting StartedThe following examples show you how to integrate this extension to a FastAPI AppExample Login FormfromfastapiimportFastAPI,Request,Dependsfromfastapi.responsesimportJSONResponsefromfastapi.templatingimportJinja2Templatesfromfastapi_csrf_protectimportCsrfProtectfromfastapi_csrf_protect.exceptionsimportCsrfProtectErrorfrompydanticimportBaseModelapp=FastAPI()templates=Jinja2Templates(directory="templates")classCsrfSettings(BaseModel):secret_key:str="asecrettoeverybody"cookie_samesite:str="none"@CsrfProtect.load_configdefget_csrf_config():returnCsrfSettings()@app.get("/login")defform(request:Request,csrf_protect:CsrfProtect=Depends()):"""Returns form template."""csrf_token,signed_token=csrf_protect.generate_csrf_tokens()response=templates.TemplateResponse("form.html",{"request":request,"csrf_token":csrf_token})csrf_protect.set_csrf_cookie(signed_token,response)returnresponse@app.post("/login",response_class=JSONResponse)asyncdefcreate_post(request:Request,csrf_protect:CsrfProtect=Depends()):"""Creates a new Post"""awaitcsrf_protect.validate_csrf(request)response:JSONResponse=JSONResponse(status_code=200,content={"detail":"OK"})csrf_protect.unset_csrf_cookie(response)# prevent token reusereturnresponse@app.exception_handler(CsrfProtectError)defcsrf_protect_exception_handler(request:Request,exc:CsrfProtectError):returnJSONResponse(status_code=exc.status_code,content={"detail":exc.message})ContributionsTo contribute to the project, fork the repository and clone to your local device and install preferred testing dependencypytestAlternatively, run the following command on your terminal to do so:pipinstall-Upoetry
poetryinstallTesting can be done by the following command post-installation:poetryinstall--withtestpytestChangelog🚧 Breaking Changes (0.3.0 -> 0.3.1) The double submit updateThegenerate_csrfmethod has now been marked for deprecationThe recommended method is nowgenerate_csrf_tokenswhich returns a tuple of tokens, first unsigned
and the latter signedRecommended pattern is for the first token is aimed for returning as part of contextRecommended pattern is for the signed token to be set in client's cookie completingDouble Submit CookieTo prevent token reuse, protected endpoint can unset the signed CSRF Token in client's cookies as
per example code and recommended pattern.🚧 Breaking Changes (0.3.1 -> 0.3.2) The anti-JavaScript updateNew keys are added at setuptoken_location(eitherbodyorheader) andtoken_keyis key
where form-encoded keeps the csrf token stored, cross-checked with csrf secret in cookies.Asynchronousvalidate_csrfmethod now needs to be awaited therefore protected endpoints need to
be asynchronous as well.Run ExamplesTo run the provided examples, first you must install extra dependenciesuvicornandjinja2Alternatively, run the following command on your terminal to do sopoetryinstall--withexamplesRunning the example utilizing form submissionuvicornexamples.body:appRunning the example utilizing headers via JavaScriptuvicornexamples.header:appLicenseThis project is licensed under the terms of the MIT license.