예전에는 1.8.2를 사용하여 블로그를 구축했는데 아직 머신에 설치되어 있어서 그대로 사용했습니다. 물론 새 버전에서는 많은 부분이 수정될 것입니다. 버그가 많기 때문에 아직은 가능한 한 새로운 것을 많이 배워야 합니다. 이 글은 입문 글로 보아야 할 것 같습니다.
# 下载django pip install django==1.8.2 -i https://pypi.mirrors.ustc.edu.cn/simple/ # 创建文件夹并启动虚拟环境 virtualenv django_demo cd django_demo source bin/activate # 创建存放django文件的文件夹 mkdir learn_django cd learn_django # 创建项目 python django-admin.py startproject django_web # 创建应用 python manage.py startapp django_app # 编辑django_web中的settings.py文件,将django_app加入到apps中
이제 가장 기본적인 구성이 완료되었습니다
Django 프레임워크에서 MVC 및 MTV를 실행하는 방법을 살펴보겠습니다
.
Django도 MVC 프레임워크이지만 Django에서는 컨트롤러가 사용자 입력을 받아들이는 부분을 프레임워크 자체에서 처리하기 때문에 Django는 MTV인
모델, 뷰, 템플릿에 더 중점을 둡니다. 모델.
둘은 MTV가 MVC를 기반으로 하고 있다고 할 수 있습니다.
3. 정적 웹 개발
템플릿 레이어 만들기
learn_django에 템플릿 폴더를 만듭니다(IDE에서 만든 django 프로젝트인 경우 자동으로 생성됩니다). 이것은 시각적 템플릿을 추가하기 위한 템플릿 폴더입니다. index.html
<title>Django Learning</title> <h2>Hellow,Django!</h2>>
뷰 레이어 만들기
뷰 레이어는 일반적으로 URL을 일치시키고 해당 웹 페이지를 반환하는 뷰 함수입니다. URL 매핑 레이어를 구축하여 들어오는 URL을 기반으로 해당 뷰 함수를 찾고 해당 템플릿 렌더링 결과를 반환할 수 있습니다.
from django.shortcuts import render # Create your views here. def index(request): return render(request,'index.html')
이유는 settings.py의 템플릿 경로 설정 문제에 있습니다. 템플릿 디렉터리가 프로젝트 루트 디렉터리에 있는 경우 설정에서 템플릿 경로를 추가하면 됩니다.
4. 동적 웹 개발 앞부분은 동적을 구현해야 한다면 데이터베이스 저장소와의 상호 작용에 대해 이야기해야 하며 이에 따라 모델을 작성해야 합니다. 데이터.mysql + django 해당 데이터베이스 인터페이스 드라이버를 설치합니다. 대략 mysqldb, pymysql, mysqlclient 세 가지 유형이 있습니다.
기본적으로 웹 루트 디렉터리에 있는 sqlite3 데이터베이스를 사용합니다.
해당 mysql 정보로 수정합니다.
mysql 데이터베이스를 만들고 문자 집합을 UTF-8로 지정합니다.
models Layer
字段定义中的特殊属性
from django.db import models # Create your models here. class DjangoTest(models.Model): text = models.CharField(max_length=20) 生成迁移文件并执行迁移 python manage.py makemigrations python manage.py migrate
查看创建的信息
建立一些测试数据
在去创建views层之前,我们先对models层进行测试,看是否提取出了数据
可以用两种方法:
1、直接在models中填写提取数据
也可以写在view层,这个无所谓
运行后可能会出现,因为在项目中单独运行python文件,需要搜索环境变量,而并没有指定,所以需要进行设置
django.core.exceptions.ImproperlyConfigured: Requested setting DEFAULT_INDEX_TABLESPACE, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS.....
pycharm解决方法:https://blog.csdn.net/u011013781/article/details/52155761
2、使用django shell
# 打开django shell python manage.py shell import django django.setup() from django_app.models imoort DjangoTest as dj # 添加数据,结果见下方图片 a = dj(text="django shell test") a.save() # 查询数据,get查询单个数据,filter查询多个模型,all查询 dj.objects.all()
django admin可以帮我们快速管理后台数据
# 创建管理员 python manage.py createsuperuser ``` ![](http://oxrfjovwk.bkt.clouddn.com/18-6-29/76119583.jpg)
将我们的模型注册到admin中,打开admin.py
将我们的模型注册到admin中,打开admin.py
from django.contrib import admin # Register your models here. from models import DjangoTest admin.site.register(DjangoTest)
这样就可以在管理员界面管理模型
view与url层
当用户请求django站点上的某个页面时,django会使用路由解析模块来解析路由,默认是app目录下的urls.py。
django加载该路由解析模块,并寻找可用的urlpatterns,这是一个python列表,然后django依次匹配列表中每个url模式,在遇到第一个与请求相匹配的模式时停下来,然后调用对应的视图,视图是一个python函数(或者是一个基于类的视图)。
一个简单的路由选择模块示例:
from django.conf.urls import url from . import views urlpatterns = [ url(r'^articles/2003/$', views.special_case_2003), url(r'^articles/([0-9]{4})/$', views.year_archive), url(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive), url(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail), ]
与之对应的请求的例子:
第三个模式将与请求/articles/2005/03/匹配。Django 将调用函数views.month_archive(request, '2005', '03')。
/articles/2005/3/ 不匹配任何URL 模式,因为列表中的第三个模式要求月份应该是两个数字。
/articles/2003/ 将匹配列表中的第一个模式不是第二个,因为模式按顺序匹配,第一个会首先测试是否匹配。请像这样自由插入一些特殊的情况来探测匹配的次序。
/articles/2003 不匹配任何一个模式,因为每个模式要求URL 以一个斜线结尾。
最后一个模式将被匹配到/articles/2003/03/03/。Django 将调用函数views.article_detail(request, '2003', '03', '03')。
根据url后边的数值,赋予相应的参数:id
urls.py
from django.conf.urls import include, url from django.contrib import admin from django_app.views import index urlpatterns = [ url(r'^admin/', include(admin.site.urls)), url(r'^index/(?P<id>[0-9])/$', index), ] </id>
将对于的id参数代入查询获取数据列表中指定索引的值(忽略这的一点小细节错误)
views.py
from django.shortcuts import render from django_app.models import DjangoTest # Create your views here. def index(request,id): text = DjangoTest.objects.all() iden = int(id) context = {'text':text[iden]} return render(request,'index.html',context)
模版层
模版层语法参考
<meta charset="UTF-8"> <title>Django test</title> <h2>ID: {{ text.id }}</h2> <h2>Hello:{{ text.text }} </h2>
实际运行效果
修复前
from django.shortcuts import render from django.contrib.auth import authenticate, login import django django.setup() # Create your views here. def index(request): if request.method == 'GET': return render(request,'index.html') else: username = request.POST['username'] password = request.POST['password'] user = authenticate(username=username,password=password) if user is not None: if user.is_active: login(request, user) template = 'Hello {user}! , You can set your email is:' + request.POST.get('email') return render(request, 'index.html', {"value": template.format(user=request.user)}) else: info = "The password is valid, but the account has been disabled!" return render(request, 'index.html', {"value": info}) else: info = "The username and password were incorrect." return render(request, 'index.html', {"value": info})
如果没有添加认证选项,即使在原代码上做了更改,返回的用户也将永远是匿名用户。
由于我之前已经创建了一个超级用户(用户名:admin,密码:admin),因此可以直接使用该用户进行身份认证。
认证之后返回登录用户的用户名,我们可以自己通过post方法传入一个邮箱地址上去作为临时地址,如果用户名信息出现任何错误,返回相应的错误信息。
使用django认证系统
User对象是认证系统的核心,默认user的基本属性有username、password、email.....
代码中邮箱信息直接通过format拼接在了字符串中,然后展示在页面里,我们可以通过以下payload来获取敏感数据,将user变量中的password属性 作为变量信息进行拼接,从而进行获取
payload: {user.password}
修复后
index.html
将其他的文本信息直接存放在模版中
nbsp;html> <meta> <title>Django test</title> <h2>Hello, Django!</h2> <h3>hello {{ user }}, You can set your email is:{{ value }}</h3> views.py ..... email = request.POST.get('email') return render(request, 'index.html', {"value": email}) ...
测试与修复前
只是简单的接收post参数值,然后让其显示在页面上
views.py def index(request): if request.method == 'GET': return render(request,'index.html') else: info = request.POST.get('info') return render(request,'index.html',{"value":info}) index.html <h2>Hello, Django!</h2> <h3>{{ value }}</h3>
当键入payload时,并没有预想的弹窗,因为django自动为开发者提供了escape功能,让html代码在render之前先进行转义,然后再显示出来。
除了自动开启的escape,还有safe、autoescape、make_Safe等
autoescape测试
{% autoescape off %} <h3>{{ value }}</h3> {% endautoescape %}
当其值为off时,即存在xss漏洞
safe测试
<h2>Hello, Django!</h2> <h3>{{ value | safe }}</h3>
通过safe关闭了模版的安全机制,出现XSS漏洞
还有几种情况也可能存在XSS:
1、var mystr = "\{ \{ value | escapejs \} \}"
2、safe、make_safe、autoescape
3、DOM型XSS
4、HttpResponse返回动态内容
修复后
import cgi # Create your views here. def index(request): if request.method == 'GET': return render(request,'index.html') else: info = request.POST.get('info') info = cgi.escape(info) return render(request,'index.html',{"value":info})
使用cgi模块需要注意:
设为True,让其转义尽可能多的导致逃逸的字符。
Django QuerySet
查看django queryset执行的SQL
from django_app.models import DjangoTest as dj print dj.objects.all().query 得到 SELECT `django_app_djangotest`.`id`, `django_app_djangotest`.`text` FROM `django_app_djangotest` 简化之后就是 SELECT id,text FROM django_app_djangotest;
extra实现别名、条件、排序等
以select为例:
tag = dj.objects.all().extra(select={"tag_id":'id'})
以where为例:
在extra中,可以使用原生SQL语句作为当前的where参数进行查询。
条件为id=1,结果即查询出了一条数据
raw方法实现原生的SQL语句查询
a = dj.objects.raw('SELECT id,text FROM django_app_djangotest ')
raw()方法支持索引访问(a[0])
也可以打印当前赋予的这个变量a都有哪些方法
直接利用API来查询数据
django.connection
MySQL API
诸如mysqldb、pymysql、mysqlclient,在views层写好sql语句,根据传入的参数值来查询,得出结果后返回给模版就可以了
修复前
views.py
from django.shortcuts import render from django_app.models import DjangoTest as dj # Create your views here. def index(request): if request.method == 'GET': return render(request,'index.html') else: id = request.POST.get('id') tag = dj.objects.extra(where={'id={}'.format(id)})[0].text return render(request,'index.html',{"value":tag})
接下来就可以进行愉快的测试了
测试篇
a = dj.objects.extra(where={'id=1'})
SELECT `django_app_djangotest`.`id`, `django_app_djangotest`.`text` FROM `django_app_djangotest` WHERE (id=1asdasdad)
先输入payload查看django传递回数据库的sql语句是什么
更改后的payload
后边又构造测试了几个,SQL语句是正确,但是django传入SQL语句时会提示里边的语法问题,并且就算语法正确,也返回不了数据。(这其实有点问题,后边做完一想,没拿到mysql shell里边去测,终端里边测对了,再拿过来,这里有点懒没再弄)
又因为id的值,从而在页面中显示不出来,所以这时候想到了延时注入
在这里调用a的时候会延时3秒
我们在Web页面中进行测试
关于这里的秒数是成倍关系,以前看到过一篇帖子,说是当时间满足出现成倍的关系时,应该是查询出了多条数据,每一个row执行一次延时。
接下来就好办了
x = dj.objects.extra(where={"id=1 and if(substr((select user()),1,1)='r',sleep(3),1)"})
后边的步骤跟着盲注的流程走就OJBK了。
有时候不要直接在django shell中执行,先去mysql命令行把命令敲对了,也确实可以执行payload时候再回来测试,确保第一步先正确。
刚刚提到的是extra模块中的where子句,其他类型的数据提取方法已经在前面讨论过了,需要具体问题具体分析
修复后
views.py
from django.shortcuts import render from django_app.models import DjangoTest as dj # Create your views here. def index(request): if request.method == 'GET': return render(request,'index.html') else: id = request.POST.get('id') tag = dj.objects.extra(where=['id=%s'],params=id) info = tag[0].text return render(request,'index.html',{"value":info})
用户发送的请求再匹配到视图函数进行处理时,视图函数的相关机制会对敏感信息进行处理,导致一些恶意语句被过滤
现在测试就不会了
위 내용은 Django 개발과 공격 및 방어 테스트는 어떤가요?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!