zoukankan      html  css  js  c++  java
  • django中间件和auth模块

    Django中间件

     由django的生命周期图我们可以看出,django的中间件就类似于django的保安,请求一个相应时要先通过中间件才能到达django后端(url、views、template、models),同样后端进行响应的时候也需要经过中间件才能达到web服务网关。

    django的七个中间件

    MIDDLEWARE = [
                    'django.middleware.security.SecurityMiddleware',
                    #  一些安全设置,比如XSS脚本过滤
    
                    'django.contrib.sessions.middleware.SessionMiddleware',
                    #  session支持中间件,加入这个中间件,会在数据库中生成一个django_session的表。
     
                    'django.middleware.common.CommonMiddleware',
                    #  通用中间件,会处理一些URL,比如baidu.com会自动的处理成www.baidu.com。比如/blog/111会处理成/blog/111/自动加上反斜杠。
    
                    'django.middleware.csrf.CsrfViewMiddleware',
                     # 跨域请求伪造中间件。加入这个中间件,在提交表单的时候会必须加入csrf_token,cookie中也会生成一个名叫csrftoken的值,也会在header中加入一个HTTP_X_CSRFTOKEN的值来放置CSRF攻击。
    
                    'django.contrib.auth.middleware.AuthenticationMiddleware',
                    #  用户授权中间件。他会在每个HttpRequest对象到达view之前添加当前登录用户的user属性,也就是你可以在view中通过request访问user。
    
                    'django.contrib.messages.middleware.MessageMiddleware',
                    #  消息中间件。展示一些后台信息给前端页面。如果需要用到消息,还需要在INSTALLED_APPS中添加django.contrib.message才能有效。如果不需要,可以把这两个都删除。
    
                    'django.middleware.clickjacking.XFrameOptionsMiddleware',
                    #  防止通过浏览器页面跨Frame出现clickjacking(欺骗点击)攻击出现。
                ]        

    django中间的自定义方法

    中间件可以定义五个方法,分别是:(主要的是process_request和process_response)

    • process_request(self,request)
    • process_view(self, request, view_func, view_args, view_kwargs)
    • process_template_response(self,request,response)
    • process_exception(self, request, exception)
    • process_response(self, request, response)

    自定义中间件的示例

     1.process_request()方法

    规律
      1.请求来的时候 会经过每个中间件里面的process_request方法(从上往下)
      2.如果方法里面直接返回了HttpResponse对象 那么会直接返回 不再往下执行
    基于该特点就可以做访问频率限制,身份校验,权限校验

    2.process_response()方法

    规律
      1.必须将response形参返回 因为这个形参指代的就是要返回给前端的数据
      2.响应走的时候 会依次经过每一个中间件里面的process_response方法(从下往上)

    3.process_view()方法

      1.在路由匹配成功执行视图函数之前 触发

    4.process_exception()方法

      1.当你的视图函数报错时  就会自动执行

    5.process_template_response()方法

      1.当你返回的HttpResponse对象中必须包含render属性才会触发

    def index(request):
        print('我是index视图函数')
        def render():
            return HttpResponse('什么鬼玩意')
        obj = HttpResponse('index')
        obj.render = render
        return obj

    总结:以上方法的返回值可以是None或一个HttpResponse对象,如果是None,则继续按照django定义的规则向后继续执行,如果是HttpResponse对象,则直接将该对象返回给用户。

    中间件的proce_request方法是在执行视图函数之前执行的。

    当配置多个中间件时,会按照MIDDLEWARE中的注册顺序,也就是列表的索引值,从前到后依次执行的。

    不同的中间件之间传递的request都是同一个对象。

    如果需要自己写的中间件生效,必须继承MiddlewareMixin,而且要保证在注册时路径不能写错。

    csrf跨站请求伪造

    关于钓鱼网站的原理,比如说你登录了一个钓鱼网站的页面,和中国银行一模一样的页面,你在哪里进行转账操作,它的转账信息也确实发到了中国银行,你的账户确实也扣钱了,但是唯一不对的时收款人不是你输入的那个人,那是因为它在用户输入框的input上做了手脚,这个input没有设置name属性,而在内部,隐藏的标签里,有一个写好了name和value的input框,这样你只要点击提交,那个value(钓鱼网站受益人的账户)就会和你的转账信息一起发给中国银行。

    防止钓鱼网站的思路

    网站会给返回给用户的form表单页面 偷偷塞一个随机字符串
    请求到来的时候 会先比对随机字符串是否一致 如果不一致 直接拒绝(403)
    该随机字符串有以下特点
    1.同一个浏览器每一次访问都不一样
    2.不同浏览器绝对不会重复

    通过{% csrf_token %}来生成随机字符串

    1.form表单发送post请求的时候  需要你做得仅仅书写一句话

    {% csrf_token %}

    2.ajax发送post请求 如何避免csrf校验

    1.现在页面上写{% csrf_token %},利用标签查找  获取到该input键值信息
        {'username':'jason','csrfmiddlewaretoken':$('[name=csrfmiddlewaretoken]').val()}
        $('[name=csrfmiddlewaretoken]').val()
        
    2.直接书写'{{ csrf_token }}'
        {'username':'jason','csrfmiddlewaretoken':'{{ csrf_token }}'}
        {{ csrf_token }}
    
    3.你可以将该获取随机键值对的方法 写到一个js文件中,之后只需要导入该文件即可
        新建一个js文件 存放以下代码 之后导入即可 
        function getCookie(name) {
            var cookieValue = null;
            if (document.cookie && document.cookie !== '') {
                var cookies = document.cookie.split(';');
                for (var i = 0; i < cookies.length; i++) {
                    var cookie = jQuery.trim(cookies[i]);
                    // Does this cookie string begin with the name we want?
                    if (cookie.substring(0, name.length + 1) === (name + '=')) {
                        cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                        break;
                    }
                }
            }
            return cookieValue;
        }
        var csrftoken = getCookie('csrftoken');
    
    
        function csrfSafeMethod(method) {
          // these HTTP methods do not require CSRF protection
          return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
        }
    
        $.ajaxSetup({
          beforeSend: function (xhr, settings) {
            if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
              xhr.setRequestHeader("X-CSRFToken", csrftoken);
            }
          }
        });

    防钓鱼的处理方法有了,当如果你的网站全局都需要校验csrf的时候,又有几个不需要校验的该如何处理,相反如果你的网站全局不需要校验csrf的时候,又有几个需要校验的功能又该怎么处理。

    #先导入模块
    from django.utils.decorators import method_decorator    
    from django.views.decorators.csrf import csrf_exempt,csrf_protect

    当整个网站都不校验,只想某个功能校验时

    # 第一种方式
    # @method_decorator(csrf_protect,name='post')  # 有效的
    class MyView(View):
        # 第三种方式
        # @method_decorator(csrf_protect)
        def dispatch(self, request, *args, **kwargs):
            res = super().dispatch(request, *args, **kwargs)
            return res
    
        def get(self,request):
            return HttpResponse('get')
        # 第二种方式
        # @method_decorator(csrf_protect)  # 有效的
        def post(self,request):
            return HttpResponse('post')

    当整个网站都校验,只想某个功能不校验时

    #如果是csrf_exempt 只有两种(只能给dispatch装)   特例
    @method_decorator(csrf_exempt,name='dispatch')  # 第二种可以不校验的方式
    class MyView(View):
        # @method_decorator(csrf_exempt)  # 第一种可以不校验的方式
        def dispatch(self, request, *args, **kwargs):
            res = super().dispatch(request, *args, **kwargs)
            return res
    
        def get(self,request):
            return HttpResponse('get')
    
        def post(self,request):
            return HttpResponse('post')

    总结:装饰器中只有csrf_exempt是特例,其他的装饰器在给CBV装饰的时候 都可以有三种方式

    Auth模块

    1、Auth模块是什么

    Auth模块是Django自带的用户认证模块:

    我们在开发一个网站的时候,无可避免的需要设计实现网站的用户系统。此时我们需要实现包括用户注册、用户登录、用户认证、注销、修改密码等功能,这还真是个麻烦的事情呢。

    Django作为一个完美主义者的终极框架,当然也会想到用户的这些痛点。它内置了强大的用户认证系统--auth,它默认使用 auth_user 表来存储用户数据。

    要注意的时,使用auth模块的话最好用全套。

    createsuperuser   #创建超级用户 这个超级用户就可以拥有登陆django admin后台管理的权限

    auth模块的功能

        #查询用户
            from django.contrib import auth
            user_obj = auth.authenticate(username=username,password=password)  # 必须要用 因为数据库中的密码字段是密文的 而你获取的用户输入的是明文
        #记录用户状态
            auth.login(request,user_obj)  # 将用户状态记录到session中
        #判断用户是否登录
            print(request.user.is_authenticated)  # 判断用户是否登录  如果是你们用户会返回False
        #用户登录之后 获取用户对象
            print(request.user)  # 如果没有执行auth.login那么拿到的是匿名用户
        #校验用户是否登录
            from django.contrib.auth.decorators import  login_required
            @login_required(login_url='/xxx/')  # 局部配置
            def index(request):
                pass
            
            # 全局配置  settings文件中
            LOGIN_URL = '/xxx/'
        #验证密码是否正确
            request.user.check_password(old_password)
        #修改密码    
            request.user.set_password(new_password)
            request.user.save()  # 修改密码的时候 一定要save保存 否则无法生效
        #退出登陆
            auth.logout(request)  # request.session.flush()
        #注册用户
                # User.objects.create(username =username,password=password)  # #创建用户名的时候 千万不要再使用create 了
                # User.objects.create_user(username =username,password=password)  # 创建普通用户
                User.objects.create_superuser(username =username,password=password,email='123@qq.com')  # 创建超级用户  邮箱必填

    自定义auth_user表

    from django.contrib.auth.models import AbstractUser
    # Create your models here.
    # 第一种 使用一对一关系  不考虑
    
    # 第二种方式   使用类的继承
    class Userinfo(AbstractUser):
        # 千万不要跟原来表中的字段重复 只能创新
        phone = models.BigIntegerField()
        avatar = models.CharField(max_length=32)
    
    # 一定要在配置文件中 告诉django
    # 告诉django  orm不再使用auth默认的表  而是使用你自定义的表
    AUTH_USER_MODEL = 'app01.Userinfo'  # '应用名.类名'
    """
    1.执行数据库迁移命令
        所有的auth模块功能 全部都基于你创建的表 
        而不再使用auth_user
    """

     

  • 相关阅读:
    LoadRunner 接口测试 第一章
    Selenium WebDriver 自动化测试 第二章
    Selenium WebDriver 自动化测试 第一章
    Scala学习
    Mysql 远程连接
    Scala学习 -- 集合 Map
    Scala学习 -- 闭包
    Scala学习
    PHP + Redis 实现消息队列
    Scala Spark Streaming + Kafka + Zookeeper完成数据的发布和消费
  • 原文地址:https://www.cnblogs.com/wangnanfei/p/11586785.html
Copyright © 2011-2022 走看看