1、csrf_token的知识点
-
(1)报错分析:如果前端表单中没有加{% csrf_token %}标签的话,在django的设置中也没有注释
'django.middleware.csrf.CsrfViewMiddleware'
的话,在进行提交的时候将会在发出短信验证码的出现Forbidden (CSRF cookie not set.): /sms_codes/
报错。 - (2)csrf_token的具体作用:在渲染模板时,django会把 表单中填写的{% csrf_token %} 替换成一个服务器随机生成的token元素。在提交表单的时候,会把这个token给提交上去。
-
(3)验证csrf_token的中间件机制:django初始启动的时候就会启动
django.middleware.csrf.CsrfViewMiddleware
中间件, 这个中间件就是来验证csrf_token的。如果没有加csrf_token,就会出错。具体验证表单提交上来是否有携带相应的token值。 - (4)加crsf_token的目的:csrf_token 是为了防止csrf(跨站请求伪造)。更简单的说:就是防止黑客盗用你存在网站(cookie)上的账户密码和信息。
- (5)每一次提交csrf_token形成的token都不同。
-
(6)加了相应的csrf_token后会默认有一个隐藏的输入框,并且相应的请求也携带token值。
- (7)在本次项目的js文件中对csrf_token的获取和获取cookie值的语句如下:
// get cookie using jQuery
function getCookie(name) {
let cookieValue = null;
if (document.cookie && document.cookie !== '') {
let cookies = document.cookie.split(';');
for (let i = 0; i < cookies.length; i++) {
let cookie = jQuery.trim(cookies[i]);
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
function csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
// Setting the token on the AJAX request
$.ajaxSetup({
beforeSend: function (xhr, settings) {
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
}
}
});
2、解决Forbidden (CSRF cookie not set.)
的相应方法
- (1)在表单中添加
{% csrf_token%}
标签。 - (2)在对请求的路由中相对应的类视图中加装饰器,比如对注册、登录、找回密码的类视图加装饰器。
from django.views.decorators.csrf import ensure_csrf_cookie
from django.utils.decorators import method_decorator
@method_decorator(ensure_csrf_cookie,name='dispatch')
注意:method_decorator能够将对函数装饰的装饰器转化为对内视图进行装饰。
注意:dispatch是分发给类中的每一个函数视图。
注意:ensure_csrf_cookie就是设置相应的token值。
- (3)通过中间件在视图处理之前设置token,必须要在配置文件中注册相应的中间件,这样才能激活中间件,才能使用。以下是django自定义的中间件。
from django.middleware.csrf import get_token
from django.utils.deprecation import MiddlewareMixin
class Middleware(MiddlewareMixin):
def process_request(self, request):
get_token(request)
#注册中间件
MIDDLEWARE = [
'utils.middleware.Middleware'
]
3、Django中间件
-
Django底层主要是由wsgi server(本质为一个socket)来进行通信的,wsgi server 是一个单进程,对于每一条请求对应的路由是一个线程(在tornado中每个请求是一个协程)
网友评论