分页与网页攻击

分页

django内置分页

1、导入django类生成对象之后的方法

    # 内置分页需要导入django中的类
    from django.core.paginator import Paginator
    paginator = Paginator(user_list,10)
    # 第一个参数是我们查出来的所有的对象, 第二个参数表示的是每页显示的行数
    # 生成一个paginator对象 paginator可以点出如下的方法
    # per_page: 每页显示条目的数量(多少行)
    # count:    总数据的个数
    # num_pages: 总页数
    # page_range: 总页数的索引范围,eg: (1,10) 表示第1页到第10页
    # page:      page对象

    users = paginator.page(cur_page)    # 需要把当前页数传进去
    # 生成page对象,page对象有如下的方法
    # has_next              是否有下一页
    # next_page_number      下一页的页码
    # has_previous          是否有上一页
    # previous_page_number  上一页的页码
    # object_list           分页之后的数据列表QuerySet  列表中套对象
    # number                当前页
    # paginator             paginator对象

2、后端代码

def test(request):

    # 首先我们需要从前端获取到需要指定的当前页数
    cur_page = request.GET.get("cur_page")
    # 转成int类型
    cur_page = int(cur_page)
    # 查出所有的对象
    user_list = models.UserInfo.objects.all()
    # 内置分页需要导入django中的类
    from django.core.paginator import Paginator
    paginator = Paginator(user_list,10)

    users = paginator.page(cur_page)    # 需要把当前页数传进去

    # 然后就可以把page对象(users)传到前台进行操作
    return render(requset,"test.html",{"users":users})
后端逻辑函数

3、前端页面分页处理

{#①先把数据生成#}
<ul>
    {% for user in users.object_list %}
        <li>{{ user.name }}</li>
    {% endfor %}
</ul>

{#上一页   需要判断有没有上一页,有了才跳转#}
{% if users.has_previous %}
    <a href="/test2/?cur_page={{ users.previous_page_number }}">上一页</a>
{% else %}
    <a href="#">上一页</a>
{% endif %}

{#②生成页面编号#}
<li>
{#users(page对象)没有总共多少页的属性,但是(paginator对象有)#}
    {% for num in users.paginator.page_range %}
        <a href="/test2/?cur_page={{ num }}">{{ num }}</a>
    {% endfor %}
</li>
{#③生成上一页与下一页#}
{% if users.has_next %}
    <a href="/test2/?cur_page={{ users.next_page_number }}">下一页</a>
{% else %}
    <a href="#"></a>
{% endif %}
前端代码

自定义分页

由于django系统提供的分页功能有限,不能指定显示多少页,也不能定制一些其他东西,

所以我们自定制分页的类:如下

class CustomPage(object):

    def __init__(self, cur_page, per_page, total, show_page, url):
        """
        :param cur_page:  当前的页数
        :param per_page:  每页的行数
        :param total:     数据总行数
        :param show_page: 一共显示多少页(分页数量)
        :param url:       处理分页数据的url
        """
        self.per_page = per_page
        self.show_page = show_page
        self.url = url
        # 总行数  /  每页的行数   a 表示正数部分   b表示小数部分
        a, b = divmod(total, per_page)
        if b:
            self.num_pages = a + 1
        else:
            self.num_pages = a

        # 如果乱拼写页数,或者不写,就让页数为1
        try:
            self.cur_page = int(cur_page)
        except Exception as e:
            self.cur_page = 1
        # 如果url拼的页数小于1,让页数为1,如果拼的页数大于最大页数,让页数为最大页数
        if self.cur_page < 1:
            self.cur_page = 1
        elif self.cur_page > self.num_pages:
            self.cur_page = self.num_pages

    def get_begin(self):
        # 返回当前页开始的索引位置
        return (self.cur_page - 1) * self.per_page

    def get_stop(self):
        # 返回当前页结束的索引位置
        return self.cur_page * self.per_page

    def page_core(self):
        # 返回总体分页代码
        half = int(self.show_page / 2)
        # 总页数小于要显示的页数
        if self.num_pages <= half * 2 + 1:
            begin = 1
            stop = self.num_pages + 1

        else:
            # 提交的页数小于1
            if self.cur_page - 1 < half:
                begin = 1
                stop = 1 + 2 * half + 1
            # 提交的页数大于最大的页数
            elif self.cur_page + half > self.num_pages:
                begin = self.num_pages - 2 * half
                stop = self.num_pages + 1
            # 提交正常页数
            else:
                begin = self.cur_page - half
                stop = self.cur_page + half + 1

        stl = []
        stl.append('<ul class="pagination pull-right">')
        # 首页
        stl.append('<li><a href="%s?cur_page=%s">首页</a></li>'%(self.url, 1))
        # 上一页
        if self.cur_page <= 1:
            prev_page = "<li class='%s'><a href ='#' >上一页</a></li>" % ("disabled")
        else:
            prev_page = "<li><a href ='%s?cur_page=%s' >上一页</a></li>" % (self.url, self.cur_page - 1)
        stl.append(prev_page)
        # 页标
        for num in range(begin, stop):
            if num == self.cur_page:
                sta = "<li class='%s'><a href = '%s?cur_page=%s'>%s</a></li>" % ("active", self.url, num, num)
            else:
                sta = "<li><a href = '%s?cur_page=%s'>%s</a></li>" % (self.url, num, num)
            stl.append(sta)
        # 下一页
        if self.cur_page >= self.num_pages:
            next_page = "<li class='%s'><a href ='#' >下一页</a></li>" % ("disabled")
        else:
            next_page = "<li><a href ='%s?cur_page=%s' >下一页</a></li>" % (self.url, self.cur_page + 1)
        stl.append(next_page)
        # 末页
        stl.append("<li><a href='%s?cur_page=%s'>尾页</a></li>"%(self.url, self.num_pages))
        # 页面导航整体返到外面
        stl.append('</ul>')
        stl_core = ' '.join(stl)
        return stl_core

后端代码

def model_students(request):

    if not request.COOKIES:
        return redirect('/user_app/login/')
    
    # 先获得要显示的页数
    cur_page = request.GET.get("cur_page")
    # 获取数据库中数据的总行数
    total = models.Students.objects.count()
    # 调用类产生自定制分页的对象
    cpage = CustomPage(cur_page=cur_page,per_page=6,total=total,show_page=4,uri="/student_app/model_students/")
    # 获得开始显示的页数
    begin = cpage.get_begin()
    # 获得结束显示的页数
    stop = cpage.get_stop()
    # 获得生成的分页代码字符串
    page_info = cpage.page_core()
    # 通过切片找出需要显示的内容
    students = models.Students.objects.all()[begin:stop]
    # 一并传到页面中进行渲染
    return render(request, "model_students.html", {"students": students,"page_info":page_info})
后端逻辑代码

前端代码

{% for item in users %}
    <tr>
        <td>{{ item.id }}</td>
         <td>{{ item.name }}</td>
    </tr>
{% endfor %}    
<ul class="pagination">
{#需要把这xss改成safe   通过管道符 safe,这样插进来的html字符串才能被浏览器解析#}
    {{ page_info | safe }}
</ul>

网页攻击

Xss攻击

1、原理

  xss攻击为跨站脚本攻击,主要原因是用户输入的内容不可控形式为在别人的评论区,

  或者留言板写入js代码并且提交,如果我们不添加防护措施,就会造成,输入的

  js代码会被浏览器解析执行,从而让别人获取到我们浏览器中的信息

2、代码

  django中是默认有xss保护的,

  如果我们想要取消xss保护,通关 管道符 加上 safe

  前端接收参数  {{ page_info | safe }}

  后端直接传入js代码, 就可以被浏览器解析执行

CSRF攻击

  csrf攻击为跨站伪造攻击

  当我们访问了不受信任的网站时,某一个图片或者连接很有可能会将我们

  浏览器的一些信息发送到黑客的电脑上,然后他们伪造我们去一些受信任的

  网站对我们的账号进行一些操作(可以轻松拿到我们的cookie)

由此可见,普通的cookie验证防护不了这种csrf攻击,因此我们通过服务器给浏览器发送

一个token字符串进行认证

1、开启csrf验证

  a. settings中打开注释

'django.middleware.csrf.CsrfViewMiddleware',

  b. 前端表单中开启csrf_token

<form action="">
    {% csrf_token %}
    <input type="text">
</form>

  如上,我们每次请求时,服务器都会在我们的表单中添加一个隐藏的token

  会在我们下一次提交数据时带上这个token,如果和服务器的相同,就说明我们时真用户

2、当我们开启csrf认证后,想要让部分业务逻辑关闭csrf认证 

from django.views.decorators.csrf import csrf_exempt
# 先导入csrf_exempt
@csrf_exempt
def test2(request):
    pass

  这样即便开启了全局csrf认证,也能通过装饰器关闭test2的csrf认证

3、当我们关闭csrf认证后,想要让部分业务逻辑开启csrf认证

from django.views.decorators.csrf import csrf_protect
# csrf_protect
@csrf_protect
def test2(request):
    pass

  这样即便关闭了全局csrf认证,也能通过装饰器开启test2的csrf认证

4、CBV装饰器的使用

  我们上面演示的都是FBV,如果是CBV

from django.views.decorators.csrf import csrf_protect,csrf_exempt
from django.utils.decorators import method_decorator
#csrf_protect 表示关闭的全局csrf认证, 开启部分csrf认证
#csrf_exempt 表示开启全局csrf认证, 关闭部分csrf认证
# name  表示只使用于某种提交的方式
@method_decorator(csrf_exempt,name="get")
class Test(object):
    def get(self):
        pass
    def post(self):
        pass

5、ajax提交token的方式

<script>
{#    首先我们要获取到token#}
{#通过属性选择器找到存放token值的标签  $("input[name='csrfmiddlewaretoken']") #}
    csrf_token = $("input[name='csrfmiddlewaretoken']").val();
    $.ajax({
        type:"post",
        url:"/test2/",
        {#token放在headers中提交过去,并且headers里面的key时固定的#}
        headers:{"X-CSRFToken":csrf_token},
        success:function () {
        }
    })
</script>
原文地址:https://www.cnblogs.com/hesujian/p/11204319.html