Django之CSRF

网页向后端传送数据的时候有两种方式,get和post。经过设置form中的method来达到是否采用get或者是postajax

<form action="/show_all/" method="POST">
可是django中使用post的话会遇到以下的错误

这个错误的意思是csrf校验失败,request请求被丢弃掉。咱们先来了解下什么是csrf。django

CSRF, Cross Site Request Forgery, 跨站点伪造请求。举例来说,某个恶意的网站上有一个指向你的网站的连接,若是某个用户已经登陆到你的网站上了,那么当这个用户点击这个恶意网站上的那个连接时,就会向你的网站发来一个请求,你的网站会觉得这个请求是用户本身发来的,其实呢,这个请求是那个恶意网站伪造后端

举个例子:浏览器

假如用户abc登陆了银行的网站,而且向abc2进行了转帐,对银行发送的请求是 http://bank.example/withdraw?account=abc&amount=1000000&for=abc2. 一般状况下,请求发送到服务器后,服务器会首先验证是不是合法的session,若是是则转帐成功。假设黑客也有一样银行的帐号。他知道转帐的时候会生成如上的请求连接。黑客也能够发送一样的请求给服务器要求转帐给本身。可是服务器校验他的这个请求不是合法的session。所以黑客想到了CSRF的方式。他本身作一个网站,在网站中发下以下连接:http://bank.example/withdraw?account=abc&amount=1000000&for=heike 而且经过广告或其余的方式诱使abc点击这个连接,上述 url 就会从 abc的浏览器发向银行,而这个请求会附带 abc浏览器中的 cookie 一块儿发向银行服务器。大多数状况下,该请求会失败,由于他要求 abc 的认证信息。可是,若是 abc 当时恰巧刚访问他的银行后不久,他的浏览器与银行网站之间的 session 还没有过时,浏览器的 cookie 之中含有 abc 的认证信息。这时,悲剧发生了,这个 url 请求就会获得响应,钱将从 abc 的帐号转移到黑客的帐号,而 abc 当时绝不知情安全

那么解决办法是什么呢:服务器

CSRF 攻击之因此可以成功,是由于黑客能够彻底伪造用户的请求,该请求中全部的用户验证信息都是存在于 cookie 中,所以黑客能够在不知道这些验证信息的状况下直接利用用户本身的 cookie 来经过安全验证。要抵御 CSRF,关键在于在请求中放入黑客所不能伪造的信息,而且该信息不存在于 cookie 之中。能够在 HTTP 请求中以参数的形式加入一个随机产生的 token,并在服务器端创建一个拦截器来验证这个 token,若是请求中没有 token 或者 token 内容不正确,则认为多是 CSRF 攻击而拒绝该请求。cookie

那么回到django中的post失败有两种解决办法:session

解决办法一:将csrf中间层注释掉ide

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
#    'django.middleware.csrf.CsrfViewMiddleware',
   
'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
此时将不会进行csrf的校验,但如前面所述,这是一种不安全的行为。并且djano也不推荐使用
 
解决办法二:
在前面的提示中有这样一句话:

In any template that uses a POST form, use the csrf_token tag inside the <form> element if the form is for an internal URL, e.g.:post

<form action="" method="post">{% csrf_token %}

也就是说在网页中加入csrf_token的标签就能够经过csrf校验
Django 提供的 CSRF 防御机制:
1 django 第一次响应来自某个客户端的请求时,会在服务器端随机生成一个 token,把这个 token 放在 cookie 里。而后每次 POST 请求都会带上这个 token,这样就能避免被 CSRF 攻击。
2 在返回的 HTTP 响应的 cookie 里,django 会为你添加一个 csrftoken 字段,其值为一个自动生成的 token,在全部的 POST 表单时,必须包含一个 csrfmiddlewaretoken 字段 (只须要在模板里加一个 tag, django 就会自动帮你生成,见下面)
3 在处理 POST 请求以前,django 会验证这个请求的 cookie 里的 csrftoken 字段的值和提交的表单里的 csrfmiddlewaretoken 字段的值是否同样。若是同样,则代表这是一个合法的请求,不然,这个请求多是来自于别人的 csrf 攻击,返回 403 Forbidden.
4 在全部 ajax POST 请求里,添加一个 X-CSRFTOKEN header,其值为 cookie 里的 csrftoken 的值
相关文章
相关标签/搜索