CSRF相关的装饰器 json数据 xml ajax
一丶CSRF相关的装饰器
from django.utils.decorators import method_decorator # 给cbv加上装饰器
from django.views import View
from django.views.decorators.csrf import csrf_exempt, csrf_protect
### 在FBV模式下
# csrf_exempt 豁免csrf校验
# csrf_protect 强制进行csrf校验
'''
csrf_exempt: #豁免,不进行csrf校验
csrf_protect: #强制执行csrf校验
'''
二丶CSRF的流程
1.想要通过csrf校验的前提是. 必须有csrftoken的cookie.
### 生成 input标签 携带csrf的值
# 1. {% csrf_token %}
<input type="hidden" name="csrfmiddlewaretoken" value="uVC0dQAf4R9cIfT57OUGFgQTiggYFUD4qwhBYPVLJSwPN2RoiMQSWGNvpFnnkmAX">
# 2. 浏览器中的session中存在csrftoken值
# csrftoken WK1xwuRTVyVLDMTfgsx8cpPDOJZPCAhZSlG8htcpAzioIzRyrqtktPMfV86eh2eS
from django.views.decorators.csrf import ensure_csrf_cookie # 确保有session的值
2.从cookie中获取csrftoken的值 与 POST提交的数据中的csrfmiddlwaretoken的值做比对
# 如果从request.POST中获取不到csrfmiddlewaretoken的值,会尝试从请求头中获取x-csrftoken的值,并且拿这个值与csrftoken的值做对比,对比成功也能通过校验。
CSRF源码 如下:
#### csrf的源码
from django.middleware.csrf import CsrfViewMiddleware
### 主要了解 三个方法:
# def process_request(self, request): 处理请求
# def process_view(self, request, callback, callback_args, callback_kwargs): 视图处理
# def process_response(self, request, response): 响应处理
class CsrfViewMiddleware(MiddlewareMixin):
"""
Middleware that requires a present and correct csrfmiddlewaretoken
for POST requests that have a CSRF cookie, and sets an outgoing
CSRF cookie.
This middleware should be used in conjunction with the csrf_token template
tag.
"""
# The _accept and _reject methods currently only exist for the sake of the
# requires_csrf_token decorator.
def _accept(self, request):
# Avoid checking the request twice by adding a custom attribute to
# request. This will be relevant when both decorator and middleware
# are used.
request.csrf_processing_done = True
return None
def _reject(self, request, reason):
logger.warning(
'Forbidden (%s): %s', reason, request.path,
extra={
'status_code': 403,
'request': request,
}
)
return _get_failure_view()(request, reason=reason)
def _get_token(self, request):
if settings.CSRF_USE_SESSIONS:
try:
return request.session.get(CSRF_SESSION_KEY)
except AttributeError:
raise ImproperlyConfigured(
'CSRF_USE_SESSIONS is enabled, but request.session is not '
'set. SessionMiddleware must appear before CsrfViewMiddleware '
'in MIDDLEWARE%s.' % ('_CLASSES' if settings.MIDDLEWARE is None else '')
)
else:
try:
cookie_token = request.COOKIES[settings.CSRF_COOKIE_NAME]
except KeyError:
return None
csrf_token = _sanitize_token(cookie_token)
if csrf_token != cookie_token:
# Cookie token needed to be replaced;
# the cookie needs to be reset.
request.csrf_cookie_needs_reset = True
return csrf_token
def _set_token(self, request, response):
if settings.CSRF_USE_SESSIONS:
request.session[CSRF_SESSION_KEY] = request.META['CSRF_COOKIE']
else:
response.set_cookie(
settings.CSRF_COOKIE_NAME,
request.META['CSRF_COOKIE'],
max_age=settings.CSRF_COOKIE_AGE,
domain=settings.CSRF_COOKIE_DOMAIN,
path=settings.CSRF_COOKIE_PATH,
secure=settings.CSRF_COOKIE_SECURE,
httponly=settings.CSRF_COOKIE_HTTPONLY,
)
# Set the Vary header since content varies with the CSRF cookie.
patch_vary_headers(response, ('Cookie',))
def process_request(self, request):
csrf_token = self._get_token(request) # 从cookie中获取csrftoken的cookie值