一、发现问题:
日志中每隔10分钟会出现一次’WARNING Forbidden (CSRF cookie not set.): /'报错。
#setting中设置日志格式如下:
logging.basicConfig(level=logging.INFO,
format='%(asctime)s %(pathname)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
datefmt='%Y-%m-%d %H:%M:%S',
filename='./serverlog2023.log',
filemode='a'
)
#serverlog2023.log中提示:
2023-05-05 15:14:53 C:\Users\Administrator\AppData\Local\Programs\Python\Python37\lib\site-packages\django\middleware\csrf.py[line:160] WARNING Forbidden (CSRF cookie not set.): /
根据WARNING 提示找到csrf.py的160行, ‘Forbidden (%s): %s’, reason, request.path,,发现request.path打印为‘/’,并没有函数路径,无法定位到是哪个函数请求缺少csrf验证。
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)
二、尝试操作:
路径为空,猜测是主程序的请求问题,按照网上的方法,把view.py中所有含“request.method == ‘POST’:”的函数前都加上@csrf_exempt,前端html中所有含method="post"的form标签都加上 {% csrf_token %},仍然报错。
三、解决方案:
根据路径"/",在url.py中找到url(r’^$', lrsupport.views.home, name=‘home’),对应函数是home(),加上@csrf_exempt,停止WARNING 。
@csrf_exempt
def home(request):
c = csrf(request)
return render_to_response('home.html', context=c)
四、原因解析:
在Django中,csrf(request)
函数用于生成和验证CSRF令牌。CSRF(Cross-Site Request Forgery)是一种攻击方式,攻击者通过伪造用户的请求来执行恶意操作。
在视图函数中,可以使用csrf(request)
函数来验证CSRF令牌。例如:
from django.shortcuts import render
from django.views.decorators.csrf import csrf_protect
@csrf_protect
def my_view(request):
if request.method == 'POST':
# 验证CSRF令牌
c = csrf(request)
if not c:
# CSRF验证失败,处理逻辑
return render(request, 'csrf_error.html')
else:
# CSRF验证成功,处理逻辑
return render(request, 'success.html')
else:
# GET请求处理逻辑
return render(request, 'form.html')
在上述示例中,@csrf_protect
装饰器用于开启CSRF保护。当请求为POST方法时,会调用csrf(request)
函数来验证CSRF令牌。如果验证失败,则返回一个错误页面;如果验证成功,则执行相应的处理逻辑。
需要注意的是,为了使CSRF保护生效,你需要在HTML表单中添加CSRF令牌。可以使用Django模板中的{% csrf_token %}
标签来生成CSRF令牌。例如:
<form method="post" action="/my_view/">
{% csrf_token %}
<!-- 其他表单字段 -->
<input type="submit" value="提交">
</form>
在上述示例中,{% csrf_token %}
标签会生成一个隐藏的input字段,其中包含了CSRF令牌。当表单提交时,CSRF令牌会被包含在请求中,从而进行验证。
通过以上步骤,你可以在Django中进行CSRF保护,并使用csrf(request)
函数来验证CSRF令牌。
原来需要验证的不是“request.method == ‘POST’:”请求,而是csrf(request)这一句。