csrfmiddlewaretoken和csrftoken之间的关系是什么?

时间:2017-12-28 06:46:10

标签: django csrf

我正在与Django合作创建一个网站,并对CSRF提出了一些问题。我使用FragmentManager manager = getFragmentManager(); FragmentB fragment = new FragmentB(); FragmentTransaction transaction = manager.beginTransaction(); transaction.replace(R.id.container, fragment).addToBackStack(null); transaction.commit(); 并在POST表单中添加django.middleware.csrf.CsrfViewMiddleware

当我测试网站时:

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

然后,我得到了饼干

GET / HTTP/1.1
Host: 123.207.137.168:8000

但是在html中:

Set-Cookie:csrftoken=Ev8veOH89vFDnG3a0GJUsMXA1oGZXxqXRw2nFWiKrvZ9UE10niTlZCiOxdnoKfTv; expires=Thu, 27-Dec-2018 06:37:41 GMT; Max-Age=31449600; Path=/

所以我想知道为什么<input type='hidden' name='csrfmiddlewaretoken' value='JswHLk4fNpxHkh0OObD1uKiOxSDUzkMDWtqzcsFR5pRdRfYEbNNs1AD23Hkjm2fb' /> csrftoken不同,如果请求来自用户或黑客,服务器如何使用这两个值来有效?

1 个答案:

答案 0 :(得分:2)

There are some answers in the docs, but looking at the code really solves this "mystery" Basically what django does is the following:

  1. Craft a CSRF secret key
  2. Add a random salt to it and set the salted result as a CSRF cookie (csrftoken)
  3. When user opens a form/request/anything, check if the user has the CSRF cookie set (if they don't have it, craft it as above). If they have it, fetch it, strip the salt and get the real secret, add a random salt and use this as another token (csrfmiddlewaretoken).

Now when you make a POST request for example, the following happens

  1. You send the csrfmiddlewaretoken
  2. Django unsalts the csrf cookie (csrftoken)
  3. Django unsalts the token you sent (csrfmiddlewaretoken)
  4. Django compares them. If the two match, you're ok.

This method with the two tokens is called Double-Submit Cookie. Django's way with the salting allows to keep the same csrf secret for some time without having to renew the key for every request