CSRF Failed: Referer checking failed - no Referer


postman模擬登錄出了這個錯誤,其實看標題就知道大概是怎么回事,網上大概找了辦法,也沒說到位,所以干脆自己找源碼了.

問題很明顯就是出在 CSRF 上,理所當然去查看 CsrfViewMiddleware 中間件:

 1 class CsrfViewMiddleware(object):
 2 
 3     def _accept(self, request):
 4        
 5         request.csrf_processing_done = True
 6         return None
 7 
 8     def _reject(self, request, reason):
 9         logger.warning('Forbidden (%s): %s', reason, request.path,
10             extra={
11                 'status_code': 403,
12                 'request': request,
13             }
14         )
15         return _get_failure_view()(request, reason=reason)
16 
17     def process_view(self, request, callback, callback_args, callback_kwargs):
18 
19         if getattr(request, 'csrf_processing_done', False):
20             return None
21 
22         try:
23             csrf_token = _sanitize_token(
24                 request.COOKIES[settings.CSRF_COOKIE_NAME])
25             request.META['CSRF_COOKIE'] = csrf_token
26         except KeyError:
27             csrf_token = None
28            
29             request.META["CSRF_COOKIE"] = _get_new_csrf_key()
30         
31             return None
32 e that anything not defined as 'safe' by RFC2616 needs protection
33         if request.method not in ('GET', 'HEAD', 'OPTIONS', 'TRACE'):
34             if getattr(request, '_dont_enforce_csrf_checks', False):
35                 return self._accept(request)
36 
37             if request.is_secure():
38                 referer = force_text(
39                     request.META.get('HTTP_REFERER'),
40                     strings_only=True,
41                     errors='replace'
42                 )
43                 if referer is None:
44                     return self._reject(request, REASON_NO_REFERER)      # 問題就出在這里  
45 
46                 good_referer = 'https://%s/' % request.get_host()
47                 if not same_origin(referer, good_referer):
48                     reason = REASON_BAD_REFERER % (referer, good_referer)
49                     return self._reject(request, reason)
50 
51             if csrf_token is None:
52                 return self._reject(request, REASON_NO_CSRF_COOKIE)
53             request_csrf_token = ""
54             if request.method == "POST":
55                 try:
56                     request_csrf_token = request.POST.get('csrfmiddlewaretoken', '')
57                 except IOError:
58                     pass
59 
60             if request_csrf_token == "":
61                 request_csrf_token = request.META.get('HTTP_X_CSRFTOKEN', '')
62 
63             if not constant_time_compare(request_csrf_token, csrf_token):
64                 return self._reject(request, REASON_BAD_TOKEN)
65 
66         return self._accept(request)

首先在文件里面搜索報錯的信息字符串,找到這個:

REASON_NO_REFERER = "Referer checking failed - no Referer."

然后搜索 REASON_NO_REFERER 就會找到上面的那一段代碼中出錯的位置.(為什么寫這些東西,因為我有個同學就是從來都不會找出錯原因,方法有時候比結論更重要)

然后代碼里面說的很清楚了, referer = request.META.get('HTTP_REFERER') 

這就說明請求頭里面沒有 REFERER這個信息,都知道的,Django會把自定義的請求頭大寫並在前面添加 HTTP_ ,所以在postman的header里面添加這個 referer 字段就好了.

注意,referer的格式是 https://www.domain.com/.          后面有個點

然后就OK了

 

 

多說兩句,看看人家django多貼心,如果是post請求的話,會嘗試從兩個地方獲取csrftoken,請求體里面可以放,就算忘了放,還會從請求頭里面拿(54行 - 64行)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM