django使用ajax PUT/DELETE方法请求报错解决“forbidden (CSRF token missing or incorrect.)
Django IIS使用ajax PUT/DELETE方法请求报错解决
1.报错内容:
后端报错内容
[2022-11-15 10:11:48,961] [log.py:log_response->228]-[WARNING]-Forbidden: /teams/data_structure_detail/45/
[2022-11-15 10:11:48,961] [basehttp.py:log_message->157]-[WARNING]-"PUT /teams/data_structure_detail/45/ HTTP/1.1" 403 58
前端返回报错
2.报错原因
django,会对合法的跨域访问做这样的检验,cookies里面存储的’csrftoken’,和post的header里面的字段”X-CSRFToken’作比较,只有两者匹配,才能通过跨域检验。否则会返回这个错误:CSRF Failed: CSRF token missing or incorrect,而我们django的后端认证csrf方式是自带的用户验证机制。即使注释了CSRF中间件也还是一样无法通过
点开django CSRF中间件的源码我们可以看到返回报错的源码
class CsrfViewMiddleware(MiddlewareMixin):
"""
Require a present and correct csrfmiddlewaretoken for POST requests that
have a CSRF cookie, and set 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
############################### CSRF检测报错 #######################################
def _reject(self, request, reason):
response = _get_failure_view()(request, reason=reason)
log_response(
'Forbidden (%s): %s', reason, request.path,
response=response,
request=request,
logger=logger,
)
return response
。。。
。。。
。。。
def process_view(self, request, callback, callback_args, callback_kwargs):
if getattr(request, 'csrf_processing_done', False):
return None
# Wait until request.META["CSRF_COOKIE"] has been manipulated before
# bailing out, so that get_token still works
if getattr(callback, 'csrf_exempt', False):
return None
#################### 前端ajax传来的方法里没有找到,因此无法进去进入_accept函数 给request.csrf_processing_done = True 赋值 #############################
# Assume that anything not defined as 'safe' by RFC7231 needs protection
if request.method not in ('GET', 'HEAD', 'OPTIONS', 'TRACE'):
if getattr(request, '_dont_enforce_csrf_checks', False):
# Mechanism to turn off CSRF checks for test suite.
# It comes after the creation of CSRF cookies, so that
# everything else continues to work exactly the same
# (e.g. cookies are sent, etc.), but before any
# branches that call reject().
return self._accept(request)
我们再来看看_accept函数的翻译
# 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
class ClientHandler(BaseHandler):
"""
A HTTP Handler that can be used for testing purposes. Use the WSGI
interface to compose requests, but return the raw HttpResponse object with
the originating WSGIRequest attached to its ``wsgi_request`` attribute.
"""
def __init__(self, enforce_csrf_checks=True, *args, **kwargs):
self.enforce_csrf_checks = enforce_csrf_checks
super().__init__(*args, **kwargs)
def __call__(self, environ):
# Set up middleware if needed. We couldn't do this earlier, because
# settings weren't available.
if self._middleware_chain is None:
self.load_middleware()
request_started.disconnect(close_old_connections)
request_started.send(sender=self.__class__, environ=environ)
request_started.connect(close_old_connections)
request = WSGIRequest(environ)
# sneaky little hack so that we can easily get round
# CsrfViewMiddleware. This makes life easier, and is probably
# required for backwards compatibility with external tests against
# admin views.
"""
译文
#鬼鬼祟祟的小黑客,这样我们就可以轻松绕过
# CsrfViewMiddleware。这使生活更容易,而且可能是
#需要与外部测试向后兼容
# admin视图。
request._dont_enforce_csrf_checks = not self.enforce_csrf_checks
通过以上问题的分析,我们可以通过以下的解决方法来解决ajax PUT/DELETE方法跨域检测不通过的文通
3.解决方法
定义一个中间件,然后在setting.py文件中注册即可
自定义中间件CsrfExemptMiddleware.py
from django.utils.deprecation import MiddlewareMixin
class CsrfExemptMiddleware(MiddlewareMixin):
def process_request(self, request):
request.csrf_processing_done = True
request._dont_enforce_csrf_checks = True
在setting.py
中注册中间件
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware',
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'system_register.middleware.CsrfExemptMiddleware',
...
]
注:另外如果是IIS部署项目的化有可能会遇到项目无法使用PUT/DELETE方法的问题,此时我们需要在web.config
文件中增加以下代码
<modules runAllManagedModulesForAllRequests="true">
<remove name="WebDAVModule"/>
</modules>
<handlers>
<remove name="WebDAV" />
</handlers>
下面是完整的配置代码
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<modules>
<remove name="WebDAVModule" />
</modules>
<handlers>
<remove name="WebDAV" />
<add name="Python FastCGI" path="*" verb="*" modules="FastCgiModule" scriptProcessor="D:\Program Files (x86)\Python\Python37\python.exe|E:\xxxxxxxxx\xxxxxxxxx\wfastcgi.py" resourceType="Unspecified" requireAccess="Script" />
</handlers>
<httpRedirect enabled="false" destination="" exactDestination="false" childOnly="false" httpResponseStatus="Permanent" />
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="419430400" />
</requestFiltering>
</security>
<httpErrors errorMode="Detailed" />
<asp scriptErrorSentToBrowser="true" />
</system.webServer>
<appSettings>
<add key="WSGI_HANDLER" value="django.core.wsgi.get_wsgi_application()" />
<add key="PYTHONPATH" value="E:\xxxxxxxxx\xxxxxxxxx" />
<add key="DJANGO_SETTINGS_MODULE" value="system_register.settings" />
</appSettings>
<system.web>
<httpRuntime executionTimeout="6000" maxRequestLength="419430400" />
<customErrors mode="Off" />
<compilation debug="true" />
</system.web>
</configuration>
重启项目重新访问接口即可。
以上的内容希望对你有帮助!
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanheeahae
系列文章
更多
同类精品
更多
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
微信运动停用后别人还能看到步数吗
PHP中文网 07-22 -
excel打印预览压线压字怎么办
PHP中文网 06-22