rest_framework默認是對所有的視圖函數進行了csrf_exempt認證豁免。
如果你使用了postman等工具測試會發(fā)現確實是這樣,但是在實際的使用過程中,我們在發(fā)送post,update,patch,delete請求時依然會收到403 Forbidden 權限限制。
一、為什么會遇到這種情況
查看APIView的as_view()源碼,最后一行代碼:
# Note: session based authentication is explicitly CSRF validated,
# all other authentication is CSRF exempt.
return csrf_exempt(view)
翻譯過來就是:
基于`session`的用戶認證明確的要求了`CSRF`認證,其它的用戶認證類都進行豁免了。
如果你對rest_framework的用戶認證不熟悉的話,可以看看http://www.itdecent.cn/p/2079065de888
在rest_framework.settings文件中,包含了rest_framework所有的默認設置,其中關于用戶認證類的設置:
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.BasicAuthentication'
],
問題就出在SessionAuthentication中:
SessionAuthentication只對經過身份驗證的用戶執(zhí)行CSRF檢查,只有這樣才能避免CSRF攻擊,http://www.itdecent.cn/p/3b3264061b26講述了什么是csrf攻擊。
而對匿名用戶,則不進行csrf驗證,這就是為什么使用postman等工具能夠在不攜帶csrf-token的情況下進行訪問,而在正式環(huán)境中確會收到403 Forbidden
class SessionAuthentication(BaseAuthentication):
def authenticate(self, request):
"""
Returns a `User` if the request session currently has a logged in user.
Otherwise returns `None`.
"""
# Get the session-based user from the underlying HttpRequest object
user = getattr(request._request, 'user', None)
# Unauthenticated, CSRF validation not required
if not user or not user.is_active:
return None
# 非匿名用戶,則需要進行 CSRF 驗證
self.enforce_csrf(request)
# CSRF passed with authenticated user
return (user, None)