六十六:CSRF攻击与防御之CSRF防御之ajax防御和ajax封装
app里面还是要绑定CSRFProtect

from flask_wtf import CSRFProtect # flask_wtf 已经提供CSRF的防御手段
CSRFProtect(app) # 绑定app
登录页的js

$(function () {
$('#submit').click(function (event) {
event.preventDefault(); // 阻止默认form提交表单行为
var email = $('input[name=email]').val();
var password = $('input[name=password]').val();
var csrf_token = $('input[name=csrf_token]').val();
// ajax
$.post({
'url': '/login/',
'data': {
'email': email,
'password': password,
'csrf_token': csrf_token
},
'success': function (data) {
console.log(data)
},
'fail': function (error) {
console.log(error)
}
});
});
});
在页面里面引入js

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登录</title>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
<script src="{{url_for('static', filename='login.js')}}"></script>
</head>
<body>
<form action="" method="post">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
<table>
<tbody>
<tr>
<td>邮箱:</td>
<td><input type="text" name="email"></td>
</tr>
<tr>
<td>密码:</td>
<td><input type="text" name="password"></td>
</tr>
<tr>
<td></td>
<td><input id="submit" type="submit" value="点击登录"></td>
</tr>
</tbody>
</table>
</form>
</body>
</html>
请求页面


以上方法虽能使用csrf_token防御,可需要在每一个提交页面都写,flask推荐的方式是将csrf_token()放到meta标签下下,发送数据时,放到头部信息中
使用jinja的模板继承功能,base模板:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<meta name="csrf_token" content="{{ csrf_token() }}">
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
{% block head %}{% endblock %}
</head>
<body>
<nav>导航条</nav>
{% block body %}{% endblock %}
<footer>底部</footer>
</body>
</html>
登录页继承base模板

{% extends 'base.html' %}
{% block head %}
<script src="{{url_for('static', filename='login.js')}}"></script>
{% endblock %}
{% block body %}
<form action="" method="post">
<table>
<tbody>
<tr>
<td>邮箱:</td>
<td><input type="text" name="email"></td>
</tr>
<tr>
<td>密码:</td>
<td><input type="text" name="password"></td>
</tr>
<tr>
<td></td>
<td><input id="submit" type="submit" value="点击登录"></td>
</tr>
</tbody>
</table>
</form>
{% endblock %}
登录页的js,将csrf放到头部信息

$(function () {
$('#submit').click(function (event) {
event.preventDefault(); // 阻止默认form提交表单行为
var email = $('input[name=email]').val();
var password = $('input[name=password]').val();
var csrf_token = $('meta[name=csrf_token]').attr('content');
//设置头部信息
$.ajaxSetup({
'beforeSend': function (xhr, settings) {
if(!/^(GET|HEAD|OPTIPNS|TRACE)$/i.test(settings.type) && !this.crossDomain){
xhr.setRequestHeader('X-CSRFToken', csrf_token)
}
}
});
// ajax
$.post({
'url': '/login/',
'data': {
'email': email,
'password': password,
},
'success': function (data) {
console.log(data)
},
'fail': function (error) {
console.log(error)
}
});
});
});
访问

由于每个js请求都需要在头部信息里面添加此参数,所以可以将添加头部信息拿出来封装
封装一个统一的ajax,每次自动获取csrftoken并加到头部信息中

var http = {
'get':function (args) {
args['method'] = 'get';
this.ajax(args);
},
'post':function (args) {
args['method'] = 'post';
this.ajax(args);
},
'ajax':function (args) { // 将头部信息放到请求
this._ajaxSetup();
$.ajax(args);
},
'_ajaxSetup':function(){ // 将csrftoken放到头部信息
$.ajaxSetup({
'beforeSend': function (xhr, settings) {
if(!/^(GET|HEAD|OPTIPNS|TRACE)$/i.test(settings.type) && !this.crossDomain){
var csrf_token = $('meta[name=csrf_token]').attr('content'); // 获取csrf_token
xhr.setRequestHeader('X-CSRFToken', csrf_token)
}
}
});
}
};
登录页的js,使用自定义的ajax机制

$(function () {
$('#submit').click(function (event) {
event.preventDefault(); // 阻止默认form提交表单行为
var email = $('input[name=email]').val();
var password = $('input[name=password]').val();
// 使用自定义的ajax
http.post({
'url': '/login/',
'data': {
'email': email,
'password': password,
},
'success': function (data) {
console.log(data)
},
'fail': function (error) {
console.log(error)
}
});
});
});
base模板中导入ajax的js

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<meta name="csrf_token" content="{{ csrf_token() }}">
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
<script src="{{ url_for('static', filename='send_http.js') }}"></script>
{% block head %}{% endblock %}
</head>
<body>
<nav>导航条</nav>
{% block body %}{% endblock %}
<footer>底部</footer>
</body>
</html>
请求



这样发送请求的时候使用自己封装的ajax就可以实现每次发送请求的时候自动在头部信息加上csrftoken信息
六十六:CSRF攻击与防御之CSRF防御之ajax防御和ajax封装的更多相关文章
- 第三百六十六节,Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)的bool组合查询
第三百六十六节,Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)的bool组合查询 bool查询说明 filter:[],字段的过滤,不参与打分must:[] ...
- “全栈2019”Java第六十六章:抽象类与接口详细对比
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...
- 《手把手教你》系列技巧篇(六十六)-java+ selenium自动化测试 - 读写excel文件 - 上篇(详细教程)
1.简介 在自动化测试,有些我们的测试数据是放到excel文件中,尤其是在做数据驱动测试的时候,所以需要懂得如何操作获取excel内的内容.由于java不像python那样有直接操作Excle文件的类 ...
- 第二百六十六节,Tornado框架-XSS处理,页码计算,页码显示
Tornado框架-XSS处理,页码计算,页码显示 Tornado框架-XSS攻击过滤 注意:Tornado框架的模板语言,读取数据已经自动处理了XSS攻击,过滤转换了危险字符 如果要使危险字符可以远 ...
- FastAPI(六十六)实战开发《在线课程学习系统》接口开发--用户注册接口开发
在前面我们分析了接口的设计,那么我们现在做接口的开发. 我们先去设计下pydantic用户参数的校验 from pydantic import BaseModel from typing import ...
- hiho一下 第六十六周
题目链接:这是一道水爆了的广搜题 #include<iostream> #include<stdio.h> #include<algorithm> #include ...
- 第六十六篇、OC_Sqlite数据库操作
#import <Foundation/Foundation.h> #import <sqlite3.h> #define kFilename @"data.sqli ...
- 第六十六节,htnl音频视频
htnl音频视频 学习要点: 1.音频和视频概述 2.video视频元素 3.audio音频元素 本章主要探讨HTML5中音频和视频元素,通过这两个原生的媒体元素向HTML页面 ...
- salesforce 零基础学习(六十六)VF页面应善于使用变量和函数(二)常用函数的使用
上一篇介绍VF中常用的变量,此篇主要内容为VF页面可以直接使用的函数,主要包括Date相关函数,Text相关函数,Information相关函数以及logic相关函数,其他相关函数,比如math相关函 ...
随机推荐
- STM32/EMC/ZILIAO
https://www.st.com/content/ccc/resource/technical/document/application_note/a2/9c/07/d9/2a/b2/47/dc/ ...
- Python twisted事件驱动网络框架 源码剖析
一.Twisted简介 Twisted是一个事件驱动的网络框架,其中包含了诸多功能,例如:网络协议.线程.数据库管理.网络操作.电子邮件等. 事件驱动简而言之,事件驱动分为二个部分:第一,注册事件:第 ...
- kylin实战(一)
kylin适用场景 OLAP 它适合数据量大,查询维度多,但是业务改动不频繁的场景.因为业务多,则kylin的cube很多.每次业务变更,kylin修改的工作量大,且每次全量跑数据耗费时间比较长. 它 ...
- puppet完全攻略(一)puppet应用原理及安装部署
puppet完全攻略(一)puppet应用原理及安装部署 2012-06-06 18:27:56 标签:puppet puppet应用原理 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出 ...
- JAVA实现图片叠加效果
import java.awt.AlphaComposite; import java.awt.Graphics2D; import java.awt.image.BufferedImage; imp ...
- 【dmp文件还原到oralce数据库】
1.数据库执行语句,创建一个用户并赋予权限 --创建用户CREATE USER test2 IDENTIFIED BY 123456 DEFAULT TABLESPACE USERS TEMPORAR ...
- Lyft 基于 Flink 的大规模准实时数据分析平台(附FFA大会视频)
摘要:如何基于 Flink 搭建大规模准实时数据分析平台?在 Flink Forward Asia 2019 上,来自 Lyft 公司实时数据平台的徐赢博士和计算数据平台的高立博士分享了 Lyft 基 ...
- linux系统下nginx/mysql/php启动、停止、重启命令
/usr/local/nginx/sbin/nginx /etc/init.d/mysql start /usr/local/php/sbin/php-fpm start #nginx命令 ...
- jQuery文档操作之克隆操作
语法: $(selector).clone(); 解释:克隆匹配的DOM元素 $("button").click(function(event) { //1.clone():克隆匹 ...
- docker的数据管理
容器中管理数据主要有两种方式: 1.数据卷:容器内数据直接映射到本地宿主机. 2.数据卷容器:使用特定容器维护数据卷 数据卷: 数据卷是一个可供容器使用的特殊目录,他将主机操作系统目录直接映射进容器. ...