Django:模板template

Posted kumata

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Django:模板template相关的知识,希望对你有一定的参考价值。

将跨站请求伪造和验证码的东西记一下

CSRF

Cross Site Request Forgery。跨站请求伪造

链接:GET请求;表单:POST请求

某些恶意的网站上,包含链接、表单、按钮、javascript。利用用户在浏览器上的认证信息试图在网站上完成某些操作,称为CSRF(跨站请求伪造)

 

例子:

设计两个页面,一个用于提交请求(POST),一个用于展示请求提交的数据

 

booktest/urls.py

 

urlpatterns = [
    url(^csrf1$,views.csrf1, name="csrf1"),
    url(^csrf2$,views.csrf2, name="csrf2"),
] 

 

booktest/views.py

def csrf1(request):
    context = {}
    return render(request, booktest/csrf1.html, context)

def csrf2(request):
    uname = request.POST[uname]
    context = {uname: uname}
    return render(request, booktest/csrf2.html, context)

templates/booktest/csrf1.html

<body>
    <form method="post" action="/booktest/csrf2">
        <input type="text" name="uname"/>
        <input type="submit" value="提交"/>
    </form>
</body>

templates/booktest/csrf2.html

<body>
    {{ uname }}
</body>

技术分享图片

输入姓名,点击提交按钮,会出现如下效果

 技术分享图片

出现这个是因为django默认使用了CSRF的认证。把Django中的CSRF功能关闭

django4/settings.py

MIDDLEWARE_CLASSES = (
    django.contrib.sessions.middleware.SessionMiddleware,
    django.middleware.common.CommonMiddleware,
    #‘django.middleware.csrf.CsrfViewMiddleware‘,
    django.contrib.auth.middleware.AuthenticationMiddleware,
    django.contrib.auth.middleware.SessionAuthenticationMiddleware,
    django.contrib.messages.middleware.MessageMiddleware,
    django.middleware.clickjacking.XFrameOptionsMiddleware,
    django.middleware.security.SecurityMiddleware,
)

 技术分享图片

改成发布模式

django4/settings.py

DEBUG = False

ALLOWED_HOSTS = [*]

然后,启动服务器。需要带上IP地址

python manage.py runserver 192.168.30.2:8080

此时,在浏览器上访问服务器的时候,输入的URLhttp://192.168.30.2:8080/booktest/csrf1 

注意:现在是真实访问服务器的场景。

任意提交数据,都可以在csrf2中显示(比如嵌入一段html代码)

<script>
for(;;) alert(123);
</script>

另外,还有一种可能。现在访问服务器上的URL http://192.168.30.2:8080/booktest/csrf1 获得一个网页的时候,可以把网页的源码抠下来。

MIDDLEWARE_CLASSES = (
    django.contrib.sessions.middleware.SessionMiddleware,
    django.middleware.common.CommonMiddleware,
    django.middleware.csrf.CsrfViewMiddleware,
    django.contrib.auth.middleware.AuthenticationMiddleware,
    django.contrib.auth.middleware.SessionAuthenticationMiddleware,
    django.contrib.messages.middleware.MessageMiddleware,
    django.middleware.clickjacking.XFrameOptionsMiddleware,
    django.middleware.security.SecurityMiddleware,
)

但是禁止了CSRF结果就会连自己都无法访问了(http://192.168.30.2:8080/booktest/csrf1 )所以不能这样做。

防止跨域攻击的方法:在csrf1.html中,在表单中添加一个标签

<body>
    <form method="post" action="/booktest/csrf2">
        {% csrf_token %}
        <input type="text" name="uname"/>
        <input type="submit" value="提交"/>
    </form>
</body>

此时,访问http://192.168.30.2:8080/booktest/csrf1 的时候,查看源码,会发现表单中多了一项

技术分享图片

这个就是CSRF的保护措施了

此时,只有在服务器的URL http://192.168.30.2:8080/booktest/csrf1  http://192.168.30.2:8080/booktest/csrf2 发送请求,才能接收。而在本地的URL file:///D:/gz1833_python/20180918/test.html http://192.168.30.2:8080/booktest/csrf2 发送请求,则会有403的错误(Forbidden CSRF verification failed)。

技术分享图片

 

验证码

技术分享图片

验证码的作用:防爬虫、减轻服务器的压力、防CSRF

原理:画一张图。图片上随机输出几个字。要求登录的人输入值要和图片随机生成的值一致

首先,我们要让服务器返回一张图片,需要安装一个库pillow

pip install pillow

安装后在python终端尝试:

 

from PIL import Image, ImageDraw, ImageFont

# Image:画布
# ImageDraw:画笔
# ImageFont:字体(推荐使用一个字体库FreeFont)

# 注意:访问服务器的图片,响应头中的MIME类型必须为image/png或image/jpeg(之前都是text/html)

编写返回图片验证码的代码

booktest/urls.py

urlpatterns = [
    url(^verifyCode$,views.verifyCode, name="verifyCode"),
] 

booktest/views.py

def verifyCode(request):
    from PIL import Image, ImageDraw, ImageFont
    import random
    # 规定宽高 宽和高的比例决定验证码的长度是多少 这里是100/25=4
    width = 100
    height = 25
    # 背景色
    bgColor = (63,63,63) # 较深
    # 创建画布
    # 参数1 mode 模式 RGB
    # 参数2 size 长度为2的元组  (width, height)
    # 参数3 color 画布的背景色 长度为3的元组 (R,G,B)
    image = Image.new(RGB, (width, height), bgColor)
    # 创建画笔
    # 参数1 im 画布对象
    # 参数2 mode 模式 默认为None 
    draw = ImageDraw.Draw(image)
    # 创建字体
    # 参数1 font 字体文件
    # 参数2 字体大小
    font = ImageFont.truetype(FreeMono.ttf, 24)
    # 文字
    text = 0123456789
    textTemp = ‘‘
    # 逐个描绘字符
    for i in range(4):
        textTemp1 = text[random.randrange(0,len(text))]
        textTemp += textTemp1
        # 使用画笔对象在画布上描绘字符
        # 参数1 xy 要描绘的字符左上角的坐标 长度为2的元组
        # 参数2 text 要描述的字符 
        # 参数3 fill 要描述的字符的颜色
        # 参数4 font 字体
        draw.text((i*25,0), textTemp1, (255,255,255), font)

    print(textTemp)        
    # 把画布保存到内存中
    #import cStringIO # python2的内存库
    import io # python3中的内存库
    buf = io.BytesIO()
    image.save(buf, png)
    # 将内存流中的内容输出到客户端
    return HttpResponse(buf.getvalue(), image/png)

接下来在网页上显示验证码

booktest/urls.py

urlpatterns = [
    url(^verifyCode$,views.verifyCode, name="verifyCode"),
    url(^verifyTest$,views.verifyTest, name="verifyTest"),
]

booktest/views.py

def verifyTest(request):
    context = {}
    return render(request, booktest/verifyTest.html, context)

templates/booktest/verifyTest.html

<body>
    <form method="post" action="/booktest/verifyTest2">
        {% csrf_token %}
        姓名:<input type="text" name="uname"/><br/>
        验证码:<input type="text" name="verifycode"/><img src="/booktest/verifyCode"><br/>
        <input type="submit" value="提交"/>
    </form>
</body>

verifyCode中,把随机产生的验证码保存到session

 

booktest/views.py

def verifyCode(request):
    from PIL import Image, ImageDraw, ImageFont
    ... ...
    print(textTemp)

    # 保存到session中
    request.session[code] = textTemp
    
    # 把画布保存到内存中
    ... ...
    

添加路由

booktest/urls.py

urlpatterns = [
    url(^verifyTest2$,views.verifyTest2, name="verifyTest2"),
]  

 

booktest/views.py

def verifyTest2(request):
    ori_code = request.session[code]
    post_code = request.POST[verifycode]
    print(ori_code:%s, post_code:%s % (ori_code, post_code))
    if ori_code == post_code:
        return HttpResponse(ok)
    else:
        return HttpResponse(fail)

访问 http://127.0.0.1:8080/booktest/verifyTest 提交正确/错误验证码,后台可以自行检查了。

 

以上是关于Django:模板template的主要内容,如果未能解决你的问题,请参考以下文章

Django的templates(模板)

vscode代码片段生成vue模板

Django框架之模板层template的一些介绍和使用

Django-06-模板(Template)

Django 模板 template

Django入门学习--深入模板(templates)