我正在實現一個可與API密鑰或CSRF令牌一起使用的API。目標是通過Web應用程序(受CSRF保護)或第三方應用程序(受API密鑰保護)來使用它。Django手動檢查CSRF令牌
基本上每個請求(都通過POST),我檢查是否有一個API密鑰。如果有一個有效的,這是很好的去。如果不是,我想回到驗證CSRF。
是否有我可以調用來驗證CSRF的函數?該視圖本身是@csrf_exempt
,因爲API密鑰需要工作。
我正在實現一個可與API密鑰或CSRF令牌一起使用的API。目標是通過Web應用程序(受CSRF保護)或第三方應用程序(受API密鑰保護)來使用它。Django手動檢查CSRF令牌
基本上每個請求(都通過POST),我檢查是否有一個API密鑰。如果有一個有效的,這是很好的去。如果不是,我想回到驗證CSRF。
是否有我可以調用來驗證CSRF的函數?該視圖本身是@csrf_exempt
,因爲API密鑰需要工作。
您可能繼承了CsrfViewMiddleware類並覆蓋了process_view方法。然後包含您的自定義中間件,而不是默認的CSRF。
from django.middleware.csrf import CsrfViewMiddleware
class CustomCsrfMiddleware(CsrfViewMiddleware):
def process_view(self, request, callback, callback_args, callback_kwargs):
if request.META.get('api_key'):
# process api key
else:
return super(CsrfViewMiddleware, self).process_view(...)
要澄清他人,爲了使用您的自定義中間件,進入您的項目的settings.py文件,刪除MIDDLEWARE_CLASSES'django.middleware.csrf.CsrfViewMiddleware'中的行並添加自己的(即'myApp.views .CustomCsrfMiddleware')。很好的解決方案,謝謝 – grez 2016-05-24 22:13:58
您可以使用內置的CSRF驗證這樣的:
from django.middleware.csrf import CsrfViewMiddleware
def check_csrf(request):
reason = CsrfViewMiddleware().process_view(request, None,(), {})
if reason:
# CSRF failed
raise PermissionException() # do what you need to do here
我已經訪問CsrfViewMiddleware
像Aldarund表明而是這種解決方案可說的更多的需求:
如果您在視圖中執行測試,那麼您可以直接返回reason
。根據how Django middleware works,當process_view
返回的東西不是None
,那麼它必須是一個HttpResponse
對象,因此它只能由視圖返回。
有些情況下您不想直接返回reason
,但如果沒有理由不這樣做,我寧願返回它,以便與其他情況下網站的行爲一致。
如果您使用測試在運行的設施,工廠的視圖,並且您已經使用CsrfViewMiddleware
站點範圍內,通常是request
將已經通過CsrfViewMiddleware
穿過一次的情況。 (是的,它可能發生。我在哪裏接收的請求它已由CsrfViewMiddleware
測試由於站點範圍的配置之後修改並重新測試通過CsrfViewMiddleWare
的情況下)。然而,中間件後設置csrf_processing_done
上request
它會對它進行測試,如果因爲此標誌而再次被調用,則不會重新測試它。因此csrf_processing_done
必須重置爲False
才能執行第二項測試。
下面是上述的說明:
from django.middleware.csrf import CsrfViewMiddleware
def view(request):
request.csrf_processing_done = False
reason = CsrfViewMiddleware().process_view(request, None,(), {})
if reason is not None:
return reason # Failed the test, stop here.
# process the request...
你並不需要檢查每個請求,如CSRF令牌應該只有真正地在使用POST和PUT請求。其次,除非您在每個請求上生成CSRF標記,否則您無法驗證CSRF標記,並且您的驗證是_optional_。 CSRF令牌與API密鑰不同。請說明你爲什麼需要CSRF。 – 2015-04-05 05:20:16