看看能不能解决
import logging
from django.conf import settings
from django.http import HttpResponseForbidden
logger = logging.getLogger(__name__)
class CsrfViewMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
response = self.get_response(request)
return response
def _reject(self, request, reason):
logger.warning(
'Forbidden (%s): %s',
reason,
request.path,
extra={
'status_code': 403,
'request': request
}
)
return HttpResponseForbidden('<h1>禁止访问</h1>')
def process_view(self, request, callback, callback_args, callback_kwargs):
if getattr(callback, 'csrf_exempt', False):
return None
if not request.csrf_processing_done:
# 确保CSRF token存在且正确
csrf_token = request.POST.get('csrfmiddlewaretoken', '')
if csrf_token == '':
csrf_token = request.META.get('HTTP_X_CSRFTOKEN', '')
if not self._compare_salted_tokens(csrf_token, request.csrf_token):
return self._reject(request, 'CSRF token缺失或不正确')
return None
def _compare_salted_tokens(self, token1, token2):
"""
将两个token通过加盐哈希算法进行比较。
"""
from django.utils.crypto import constant_time_compare
from django.utils.six.moves import range
for salt in getattr(settings, 'CSRF_SALT', ()):
expected_token = _salt_cipher_secret(token1 + salt)
actual_token = _salt_cipher_secret(token2 + salt)
if constant_time_compare(expected_token.encode(), actual_token.encode()):
return True
return False
def _salt_cipher_secret(secret):
"""
为secret添加一个salt,以便相同的secret在不同的进程中生成不同的哈希值。
"""
from django.utils.crypto import get_random_string
return get_random_string(7, 'abcdefghijklmnopqrstuvwxyz') + secret