python跨域攻击教学_Python学习————跨域问题

一:跨域请求

跨域问题

问题出现:前后端来自同一个IP的不同端口

一种奇葩的解决方法:开发的时候前后端分离,部署的时候不分离

1.同源策略

简介

同源策略,是浏览器为了保护用户信息安全的一种安全政策。

同源通常指的是 浏览器页面的 协议相同 域名相同 端口相同

同源策略的目的是为了保证用户的信息安全,防止恶意的网站窃取信息数据。

所谓的同源就是指代通信的两个地址(例如服务端接口地址与浏览器客户端页面地址)之间比较,是否协议、域名(IP)和端口相同

不同源的客户端脚本[javascript]在没有得到服务端的明确授权的情况下,浏览器会拒绝显示服务端信息提供给前端ajax/axios

2.CORS(跨域资源共享)简介

CORS是一个W3C标准,全称是"跨域资源共享",它允许浏览器向跨源的后端服务器发出ajax请求,从而克服了AJAX只能同源使用的限制。

实现CORS主要依靠后端服务器中响应数据中设置响应头信息返回的

CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。

整个CORS通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。

因此,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信

容易混淆的点:

CORS:跨域资源共享

CSRF: 跨站请求伪造

XSS: 跨站脚本攻击

3.CORS基本流程

浏览器将CORS请求分成两类:简单请求(simple request)和非简单请求(not-so-simple request)

浏览器发出CORS简单请求,只需要在头信息之中增加一个Origin字段

浏览器发出CORS非简单请求,会在正式通信之前,增加一次HTTP查询请求,称为”预检”请求(preflight)

览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段

只有得到肯定答复,浏览器才会发出正式的XMLHttpRequest请求,否则就报错。

4.解决跨域问题的3种方法

前端解决(通过代理解决)

自己解决(自己写代码)

借助第三方模块(django-cors-headers)

5.CORS两种请求详解

只要同时满足以下两大条件,就属于简单请求

① 请求方法是以下三种方法之一

HEAD

GET

POST

② HTTP的头信息不超出以下几种字段

Accept

Accept-Language

Content-Language

Last-Event-ID

Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain

凡是不同时满足上面两个条件,就属于非简单请求

6.浏览器对这两种请求的处理,是不一样的

简单请求和非简单请求的区别

简单请求:发1次请求

非简单请求:发2次请求,在发送数据之前会先发1次请求用于做“预检”看后端是否允许,只有“预检”通过后才再发送1次请求用于数据传输。

请求方式:OPTIONS

预检:

检查如果通过则允许传输数据,检查不通过则不再发送真正想要发送的消息

如何预检:

如果复杂请求是PUT等请求,则服务端需要设置允许某请求,否则“预检”不通过

Access-Control-Request-Method

如果复杂请求设置了请求头,则服务端需要设置允许某请求头,否则“预检”不通过

Access-Control-Request-Headers

二:解决跨域问题(服务端)

简单请求

1.原Django项目:apps/user/views.py

from django.http import JsonResponse

def test(request):

obj = JsonResponse({'name': 'Darker', 'age': '18'})

# 值针对简单请求

obj['Access-Control-Allow-Origin'] = '*' # 允许所有IP访问

return obj

Python

复制

2.原Django项目:apps/user/urls.py

from django.urls import path

from user import views

urlpatterns = [

path('test/', views.test),

]

Python

复制

3.原Django项目:dev.py中注释掉CSRF

4.再创建1个Django项目(用另外的端口)

① templates中创建index.html

Title

点我

$('#btn').click(function () {

$.ajax({

url: 'http://127.0.0.1:8000/user/test/',

method: 'get',

success: function (data) {

console.log(data)

}

})

})

HTML

复制

② views.py

from django.shortcuts import render

def index(request):

return render(request, 'index.html')

Python

复制

③ urls.py

from django.urls import path

from app01 import views

urlpatterns = [

path('test/', views.index),

]

Python

复制

非简单请求

原Django项目apps/user/views.py

from django.http import JsonResponse

def test(request):

obj = JsonResponse({'name': 'Darker', 'age': '18'})

if request.method == 'OPTIONS':

obj['Access-Control-Allow-Headers'] = 'Content-Type,authorization' # 或者填写 *

obj['Access-Control-Allow-Origin'] = 'http://127.0.0.1:8002' # 8002端口是当前项目的

return obj

Python

复制

新Django项目templates/index.html

Title

点我

$('#btn').click(function () {

let obj = {name: 'Darker'}

$.ajax({

url: 'http://127.0.0.1:8000/user/test/',

method: 'post',

contentType: 'application/json',

headers: {authorization: 'Darker'},

data: JSON.stringify(obj),

success: function (data) {

console.log(data)

}

})

})

HTML

复制

3.中间件处理

① 在原Django项目的根路径创建mymiddle.py - 自定义中间件

from django.utils.deprecation import MiddlewareMixin

class CoreMiddle(MiddlewareMixin):

def process_response(self, request, response):

if request.method == 'OPTIONS':

response['Access-Control-Allow-Headers'] = 'Content-Type, authorization' # 如果是 * 就代表全部IP都可以访问

response['Access-Control-Allow-Origin'] = '*'

return response

Python

复制

② 在原Django项目的dev.py的中间件中添加自定义中间件

MIDDLEWARE = [

'django.middleware.security.SecurityMiddleware',

'django.contrib.sessions.middleware.SessionMiddleware',

'mymiddle.CoreMiddle', # 这一句

'django.middleware.common.CommonMiddleware',

# 'django.middleware.csrf.CsrfViewMiddleware',

'django.contrib.auth.middleware.AuthenticationMiddleware',

'django.contrib.messages.middleware.MessageMiddleware',

'django.middleware.clickjacking.XFrameOptionsMiddleware',

]

Python

复制

③ 原Django项目apps/user/views中替换成如下代码

from django.http import JsonResponse

def test(request):

return JsonResponse({'name': 'Darker', 'age': '18'})

Python

复制

三:解决跨域问题(第三方)

1.后端配置

① 后端安装跨域模块

pip install django-cors-headers

Shell

复制

② 到dev.py中进行注册

INSTALLED_APPS = (

...

'corsheaders'

)

Python

复制

③ 到dev.py中添加中间件

MIDDLEWARE = [

...

'corsheaders.middleware.CorsMiddleware',

'django.middleware.common.CommonMiddleware', # 这个是原本就存在的

...

]

Python

复制

④ 到dev.py中添加如下代码

CORS_ALLOW_CREDENTIALS = True

CORS_ORIGIN_ALLOW_ALL = True

# CORS_ORIGIN_WHITELIST = (

# 'http://127.0.0.1:8080',

# )

CORS_ALLOWED_ORIGINS_REGEXES=[

r'^http://.*?$',

]

# CORS_ORIGIN_REGEXES_WHITELIST = (

# r'^http://.*?$',

# )

CORS_ALLOW_METHODS = (

'DELETE',

'GET',

'OPTIONS',

'PATCH',

'POST',

'PUT',

'VIEW',

)

CORS_ALLOW_HEADERS = (

'XMLHttpRequest',

'X_FILENAME',

'accept-encoding',

'authorization',

'content-type',

'dnt',

'origin',

'user-agent',

'x-csrftoken',

'x-requested-with',

'Pragma',

)

Python

复制

⑤ 设置dev.py的ALLOWED_HOSTS

ALLOWED_HOSTS = ['*']

Python

复制

2.后端测试

① (测试 - 后台)到apps/user/views中替换成如下代码

from django.http import JsonResponse

def test(request):

return JsonResponse({'name': 'Darker', 'age': '18'})

Python

复制

② (测试 - 后台)到apps/user/urls中替换成如下代码

from django.urls import path

from user import views

urlpatterns = [

path('test/', views.test),

]

Python

复制

③ 启动项目

python manage.py runserver 127.0.0.1:8000

Shell

复制

④ 访问测试

3.前端测试

① (测试 - 前台)App.vue 中换成如下代码

{{name}}

export default {

data () {

return {

name: []

}

},

mounted () {

this.$axios.get(this.$settings.base_url + '/user/test/').then(res => {

this.name = res.data

})

}

}

HTML

复制

② 启动项目

npm run serve

Shell

复制

4.测试效果

四:解决跨域问题(前端)

1.前端App.vue

我是主页

{{info}}

export default {

name: 'Home',

data () {

return {

info: []

}

},

mounted () {

this.$axios.get('/moreClassicList?sortId=1&showType=3').then(res => {

console.log(res.data)

})

}

}

HTML

复制

2.前端项目根路径的vue.config.js

const webpack = require("webpack");

module.exports = {

configureWebpack: {

plugins: [

new webpack.ProvidePlugin({

$: "jquery",

jQuery: "jquery",

"window.jQuery": "jquery",

"window.$": "jquery",

Popper: ["popper.js", "default"]

})

]

},

devServer: {

proxy: {

'/ajax': {

target: 'https://m.maoyan.com/',

changeOrigin: true

},

'/user': {

target: 'http://127.0.0.1:8000',

changeOrigin: true

}

}

}

};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值