Django中csrf_token验证原理
我多年没维护的博客园,有一篇初学Django时的笔记,记录了关于django-csrftoekn使用笔记,当时几乎是照抄官网的使用示例,后来工作全是用的flask。博客园也没有维护。直到我的博客收到了如下评论,确实把我给问倒了,而且我也仔细研究了这个问题。
1. Django是怎么验证csrfmiddlewaretoken合法性的?
2. 每次刷新页面的时候<input>中的csrf的value都会更新,每次重复登录的时候cookie的csrf令牌都会刷新,那么这两个csrf-token有什么区别?

CSRF(Cross Site Request Forgery protection),中文简称跨站请求伪造。
django 第一次响应来自某个客户端的请求时,会在服务器端随机生成一个 token,把这个 token 放在 cookie 里。然后每次 POST 请求都会带上这个 token,
这样就能避免被 CSRF 攻击。
这样子看起来似乎没毛病,但是评论中的第三个问题,每次刷新页面,form表单中的token都会刷新,而cookie中的token却只在每次登录时刷新。我对csrftoken的验证方式起了疑问,后来看了一段官方文档的解释。
When validating the ‘csrfmiddlewaretoken’ field value, only the secret, not the full token, is compared with the secret in the cookie value. This allows the use of ever-changing tokens. While each request may use its own token, the secret remains common to all.
This check is done by CsrfViewMiddleware.
官方文档中说到,检验token时,只比较secret是否和cookie中的secret值一样,而不是比较整个token。
我又有疑问了,同一次登录,form表单中的token每次都会变,而cookie中的token不便,django把那个salt存储在哪里才能保证验证通过呢。直到看到源码。
def _compare_salted_tokens(request_csrf_token, csrf_token):
# Assume both arguments are sanitized -- that is, strings of
# length CSRF_TOKEN_LENGTH, all CSRF_ALLOWED_CHARS.
return constant_time_compare(
_unsalt_cipher_token(request_csrf_token),
_unsalt_cipher_token(csrf_token),
) def _unsalt_cipher_token(token):
"""
Given a token (assumed to be a string of CSRF_ALLOWED_CHARS, of length
CSRF_TOKEN_LENGTH, and that its first half is a salt), use it to decrypt
the second half to produce the original secret.
"""
salt = token[:CSRF_SECRET_LENGTH]
token = token[CSRF_SECRET_LENGTH:]
chars = CSRF_ALLOWED_CHARS
pairs = zip((chars.index(x) for x in token), (chars.index(x) for x in salt))
secret = ''.join(chars[x - y] for x, y in pairs) # Note negative values are ok
return secret
token字符串的前32位是salt, 后面是加密后的token, 通过salt能解密出唯一的secret。
django会验证表单中的token和cookie中token是否能解出同样的secret,secret一样则本次请求合法。
同样也不难解释,为什么ajax请求时,需要从cookie中拿取token添加到请求头中。
网上有不少关于django csrf token验证原理的文章都是错的,是因为他们根本不知道csrf-token的结构组成,我也是卡在第三条评论那.然后看了官方文档,和CsrfViewMiddleware中间件源码然后才恍然大悟。
作者:邹霉霉
链接:https://www.jianshu.com/p/7fbb60001018
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
Django中csrf_token验证原理的更多相关文章
- Django中Model-Form验证
Django中Model-Form验证 class UserType(models.Model): caption=models.CharField(max_length=32) class User ...
- Django中Form验证
Django的Form主要具有一下几大功能: 生成HTML标签 验证用户数据(显示错误信息) HTML Form提交保留上次提交数据 初始化页面显示内容 一,Form验证 第一种操作:主要是这三个函数 ...
- django中csrf_token处理方式
第一:先在HTML中加入{% csrf_token %} $.ajax({ url: '{% url "ceshi:list" %}', type: 'post', dataTyp ...
- Django中csrf token验证原理
我多年没维护的博客园,有一篇初学Django时的笔记,记录了关于django-csrftoekn使用笔记,当时几乎是照抄官网的使用示例,后来工作全是用的flask.博客园也没有维护.直到我的博客收到了 ...
- Python Django缓存,信号,序列化,文件上传,Ajax登录和csrf_token验证
本节内容 models操作 Django的缓存 请求方式 序列化 Form 配合Ajax实现登录认证 上传文件 Ajax csrf_token验证方式 1 models操作 单表查询: curd(增 ...
- 广告系统中weak-and算法原理及编码验证
wand(weak and)算法基本思路 一般搜索的query比较短,但如果query比较长,如是一段文本,需要搜索相似的文本,这时候一般就需要wand算法,该算法在广告系统中有比较成熟的应 该,主要 ...
- Django中的Form表单验证
回忆一下Form表单验证的逻辑: 前端有若干个input输入框,将用户输入内容,以字典传递给后端. 后端预先存在一个Form表单验证的基类,封装了一个检测用户输入是否全部通过的方法.该方法会先定义好错 ...
- Django 中的 csrf_token 与单元测试
Django 中的 csrf_token 与单元测试 在<Python Web开发:测试驱动方法>一书中作者使用的 Django 版本是 1.7,而我使用的是1.9.7版(官网已经更新到1 ...
- Django中模块的加载原理
Django中的module的加载是通过反射来完成的,借助importlib中的import_module函数来实现的动态加载.import_module的内部通过使用了递归和线程锁,字符串的切割,实 ...
随机推荐
- LaTeX技巧006:使用pdfLaTeX时,添加PDF文件属性的方法
PDF文件中含有标题.主题.作者.关键字等属性.这些属性,在Acrobat Reader或者Foxit Reader中可以通过”文件”菜单下的”属性”查看,在Acrobat Read中还可以使用Ctr ...
- 机器学习作业(一)线性回归——Matlab实现
题目太长啦!文档下载[传送门] 第1题 简述:设计一个5*5的单位矩阵. function A = warmUpExercise() A = []; A = eye(5); end 运行结果: 第2题 ...
- Loj515 「LibreOJ β Round #2」贪心只能过样例 - Bitset,Dp
bitset的基本应用了 类似可行性背包的dp考虑 复杂度O(nmL/64) #include <bits/stdc++.h> using namespace std; bitset &l ...
- C语言移除链表元素
删除链表中等于给定值 val 的所有节点. 示例: 输入: 1->2->6->3->4->5->6, val = 6 输出: 1->2->3->4 ...
- PTA-1003 我要通过!
1003 我要通过!https://pintia.cn/problem-sets/994805260223102976/problems/994805323154440192 “答案正确”是自动判题系 ...
- AE接口编程
[转]原文链接:https://malagis.com/arcgis-engine-10-develop-handbook-2-1.html 使用 ArcGIS Engine,也就意味着使用里面的接口 ...
- Python并发学习
#Python并发 多任务 多进程 多线程 线程同步 #多任务处理 多任务处理:使得计算机可以同时处理多个任务 听歌的同时QQ聊天.办公.下载文件 实现方式:多进程.多线程 #程序和进程 程序:是一个 ...
- rest_framework:版本控制
一.作用: 用于版本的控制,区分不同的功能,对于一些新增功能的添加更新就会在新的版本中体现,有点类似于,新版本就是软件发布的新版本,和老版本相比新增或者修改了一些功能 二.内置的版本控制类: from ...
- day27 综合架构 rsync备份服务
sync软件使用方法: rsync命令 1v4 a 本地备份数据 cp [root@nfs01 backup]# cp /etc/hosts /tmp [root@nfs01 backup]# ll ...
- Python调用libsvm
# -*- coding: utf-8 -*- import os, sys path = r"D:\Program Files (x86)\libsvm-3.22\python" ...