2014-04-16 39 views
1

我有一個簡單的REST API,既需要從Web應用程序也可以從遠程服務訪問。Django:僅當某些條件適用時,CSRF檢查

遠程服務通過包含API密鑰的自定義HTTP頭進行身份驗證。

如何保護該API,使來自Web瀏覽器的請求受到CSRF保護,但是通過API密鑰進行身份驗證時CSRF檢查沒有完成?或者,一般來說,我怎樣才能針對特定視圖上的某些請求啓用CSRF保護,而不是其他問題?

目前,我有檢查的API密鑰的請求和認證API用戶大致這樣一個裝飾:

# Regular auth 
if request.user.is_authenticated(): 
    # DO CSRF verification, then continue calling the view 

elif 'HTTP_X_API_KEY' in request.META: 
    api_key = request.META['HTTP_X_API_KEY'] 
    user = authenticate(username=settings.API_USER_NAME, password=api_key) 
    login(request, user) 
    # If user is authenticated and autzorized, continue calling the view 
    # but WITHOUT invoking CSRF protection 

的問題,說是,我只希望爲普通用戶CSRF保護,但不適用於API用戶。

+0

您可以覆蓋csrf中間件並在那裏執行相同的檢查。這樣你就不必跟蹤需要保護的觀點。 – elssar

回答

0

好的,所以經過多一點修補之後,解決方案是禁用CSRF中間件,並在需要CSRF保護的所有情況下啓用csrf_protect

這在API的特殊情況下起作用,因爲無論如何每個調用都在進行裝飾,因此某些視圖被遺忘的風險可以忽略不計。

但是不是工作,然而,是相反的,使用csrf_exempt。問題在於裝飾器只在視圖上設置了csrf_exempt屬性,如果您有多個裝飾器,則該屬性可能會被再次遮罩,即使您使用functools.wraps也是如此。

此外,由於csrf_exempt在視圖上放置了一個屬性,因此無法根據請求的內容動態啓用或禁用它 - 這確實是一個非常靜態的事情。