• django 中间键 csrf 跨站请求伪造


    django中间件和auth模块

     

    Django中间件

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

    django的七个中间件

    复制代码
    MIDDLEWARE = [
                    'django.middleware.security.SecurityMiddleware',
                    'django.contrib.sessions.middleware.SessionMiddleware',
                    'django.middleware.common.CommonMiddleware',
                    'django.middleware.csrf.CsrfViewMiddleware',
                    'django.contrib.auth.middleware.AuthenticationMiddleware',
                    'django.contrib.messages.middleware.MessageMiddleware',
                    'django.middleware.clickjacking.XFrameOptionsMiddleware',
                ]
    复制代码

    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(钓鱼网站受益人的账户)就会和你的转账信息一起发给钓鱼网站。

    防止钓鱼网站的思路

    token 字段

    网站会给返回给用户的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装饰的时候 都可以有三种方式,只有csrf_exempt必须通过dispatch来装饰.

    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
    """
  • 相关阅读:
    机器学习、图像识别方面 书籍推荐 via zhihu
    网络工具 NetCat
    CSharp读取配置文件的类(简单实现)
    about future
    Google's BBR拥塞控制算法模型解析
    对称加密与非对称加密
    windows平台下新网络库RIO ( Winsock high-speed networking Registered I/O)
    在mac os下编译android -相关文章
    [原创] linux 下上传 datapoint数据到yeelink 【golang版本】同时上传2个数据点
    在 树莓派上使用 c++ libsockets library
  • 原文地址:https://www.cnblogs.com/Sunbreaker/p/11587601.html
Copyright © 2020-2023  润新知