Django的CSRF

Posted yang-china

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Django的CSRF相关的知识,希望对你有一定的参考价值。

1、什么是CSRF

django为用户实现防止跨站请求伪造的功能,通过中间件 django.middleware.csrf.CsrfViewMiddleware 来完成。

2、对于CSRF的为什么出现。

  1. 钓鱼网站的页面和正经网站的页面对浏览器来说有什么区别? (页面是怎么来的?)

    钓鱼网站的页面是由 钓鱼网站的服务端给你返回的
    正经网站的网页是由 正经网站的服务端给你返回的

    Django就是为了放置这一类的钓鱼网站等用途

  2、Django中内置了一个专门处理csrf问题的中间件

          django.middleware.csrf.CsrfViewMiddleware  这个就在我们项目的setting里面的MIDDLEWARE列表里面

    这个中间件做的事情:

      1. 在render返回页面的时候,在页面中塞了一个隐藏的input标签

    用法:
      我们在页面上 form表单 里面 写上 {% csrf_token %}
      <input type="hidden" name="csrfmiddlewaretoken"           

      value="8gthvLKulM7pqulNl2q3u46v1oEbKG7BSwg6qsHBv4zf0zj0UcbQmpbAdijqyhfE">

      这个黄色部位每一次请求都会不一样
  2. 当你提交POST数据的时候,它帮你做校验,如果校验不通过就拒绝这次请求

 

下面就是钓鱼网站的列子:

创建Django项目的时候会自动有这个插件的。我前面写的所有的都把这个注释了这一次就不注释了

正规网站:

路由系统的代码(项目/urls.py)

from django.conf.urls import url
from django.contrib import admin
from app01 import views

urlpatterns = [
    url(r^admin/, admin.site.urls),
    url(r^transfer/$, views.transfer)
]

 

视图里面(app01/views)

from django.shortcuts import render, redirect, HttpResponse
# 转账
def transfer(request):
    if request.method == "POST":
        from_ = request.POST.get("from")
        to_ = request.POST.get("to")
        money = request.POST.get("money")

        print("{} 给 {} 转了 {}钱".format(from_, to_, money))
        return HttpResponse("转账成功!")

    return render(request, "transfer.html")

 

transfer.html代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>



<h1>正经的网站</h1>
<form action="/transfer/" method="post">
      {% csrf_token %}
    <p>
        转出:
        <input type="text" name="from">
    </p>

    <p>
        转入:
        <input type="text" name="to">
    </p>
    <p>
        金额:
        <input type="text" name="money">
    </p>
    <p>
        <input type="submit" value="转账">
    </p>
</form>
</body>
</html>

 

钓鱼网站

路由系统的代码(项目/urls.py)

from django.conf.urls import url
from django.contrib import admin
from app01 import views

urlpatterns = [
    url(r^admin/, admin.site.urls),
    url(r^transfer/$, views.transfer)
]

 

视图里面的代码(app/views)

from django.shortcuts import render

# Create your views here.


def transfer(request):
    return render(request, "transfer.html")

 

transfer.html代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<h1>钓鱼的网站</h1>
<form action="http://127.0.0.1:8000/transfer/" method="post">
    <p>
        转出:
        <input type="text" name="from">
    </p>

    <p>
        转入:
        <input type="text" name="">
        <input type="text" name="to" style="display: none" value="哪吒">
    </p>
    <p>
        金额:
        <input type="text" name="money">
    </p>
    <p>
        <input type="submit" value="转账">
    </p>
</form>
</body>
</html>

 

这个只是做了简单的转账,如果都没有CSRF这个中间件那么我们就会被钓鱼网站这个隐藏的

<input type="text" name="to" style="display: none" value="哪吒">这个插件不管我们填什么转账用户都会转到这个用户里面

当我们有了CSRF的时候这个验证就不会通过,页面就回报403错误。这个就是防止跨站伪造

 





以上是关于Django的CSRF的主要内容,如果未能解决你的问题,请参考以下文章

Django:CSRF 令牌丢失或不正确。 / 避免 % csrf_token %

Django学习---CSRF

Django-csrf跨站请求伪造

Django:POST 表单需要 CSRF? GET 没有?

CSRF 令牌上的 Django 错误

jQuery + AJAX + Django = CSRF ? [复制]