• django中间件 csrf auth认证




    django中间件
    能做全局访问频率限制,身份校验,黑名单,白名单
    用法:
    新建一个文件夹,文件夹新建一个py文件,文件中写如下代码
    注意点:你写的类必须继续MiddlewareMixin
    from django.utils.deprecation import MiddlewareMixin
    from django.shortcuts import HttpResponse,render

    class MyMiddleWare(MiddlewareMixin):
    def process_request(self,request):
    print('我是第一个自定义的中间件中process_request方法')
    # return HttpResponse('我是第一个中间件里面返回的对象')
    # return render(request, 'index.html')
    # process_request方法默认不返回HttpResponse对象,如果返回了
    # 后续的中间件都不会再走,而是直接同级别走process_response方法

    def process_response(self,request,response):
    print('我是第一个自定义的中间件中process_response方法')
    return response


    django允许用户自定义中间件,并且暴露给用户五个可以自定义的方法
    1.process_request:请求到来时会执行(必须掌握)
    2.process_response:响应返回时会执行(必须掌握)
    并且需要指定每一个方法什么时候触发(必须掌握)

    3.process_view:路由匹配成功执行视图函数之前,会依次process_view方法
    4.process_exception:视图函数中报错,会依次执行process_exception方法
    5.process_template_response:视图函数必须返回render对象时才会触发process_template_response方法(了解即可)



    CSRF跨站请求伪造
    如何通过csrf校验
    <form action="" method="post">
    {% csrf_token %}
    <p>username:<input type="text" name="username"></p>
    <p>money:<input type="text" name="money"></p>
    <p>对方账户:<input type="text" name="others"></p>
    <input type="submit">
    </form>
    <input type="hidden" name="csrfmiddlewaretoken" value="HHxKItr7Z17sZxCAtybnOeV5ne5K3xnvkymENCupB5ylL8h8kWBIiklm9K10paxE">

    ajax如何通过csrf校验
    # 通过jQuery标签查找获取csrfinput框的键值对,手动加到data参数里面
    $('button').click(function () {
    $.ajax({
    url:'',
    type:'post',
    data:{'name':'jason','csrfmiddlewaretoken':$('[name=csrfmiddlewaretoken]').val()},
    success:function (data) {
    console.log(data)
    }
    })
    })

    局部使用与局部禁用csrf
    from django.views.decorators.csrf import csrf_exempt,csrf_protect

    @csrf_exempt
    def home(request):
    return HttpResponse('home')


    @csrf_protect
    def login(request):
    return HttpResponse('login')


    auth.logout(request)
    # 等价于删除session数据request.session.flush()



    auth认证
    # user = models.User.objects.filter(username=username,password=password).first()
    user = auth.authenticate(request,username=username,password=password)
    if user:
    auth.login(request,user)
    # 这一句执行完之后,其他的视图函数可以直接通过request.user获取到当前用户对象
    # 这一句话就相当于操作session记录


    # 当没有执行auth.login,request.user打印出来的是匿名用户。将session表数据删除即可演示改效果
    # 如何判断request.user用户是否通过auth.login登陆呢?request.user.is_authenticated

    # 为何执行auth.login之后,其他视图函数中就可以通过request.user拿到当前登陆对象呢?
    # 想想django的中间件中有没有一个叫Auth啥的中间件,它干了件什么事,
    # 能不能推导一下?取出session去表里面查相应的数据,然后放到request.user中,点进去看一下这个中间件确实如此





    """
    # django中间件

    什么是中间件?

    django请求生命周期完整版,中间件类似于django的门卫,数据在进入和离开时都需要经过中间件

    中间件能干嘛?

    控制用户访问频率,全局登陆校验,用户访问白名单,黑名单等

    查看django默认的三个中间件

    - Csrf
    - Session
    - Auth

    中间件的使用(5个固定的方法)

    自定义中间件

    ```python
    from django.utils.deprecation import MiddlewareMixin


    class MyMiddleWare(MiddlewareMixin):
    def process_request(self, request):
    print('我是第一个自定义的中间件的process_request!')
    # 写一个路由与视图,启动项目,查看打印结果。
    # 再写一个自定义中间件

    class MyMiddleWare(MiddlewareMixin):
    def process_request(self, request):
    print('我是第二个自定义的中间件的process_request!')
    # 诠释中间件的执行顺序


    # 在两个中间件中添加process_response方法。研究中间件消息进出的顺序
    class MyMiddleWare(MiddlewareMixin):
    def process_request(self, request):
    print('我是第一个自定义的中间件的process_request!')
    def process_response(self,request,response):
    print('我是第一个自定义的中间件的process_response')
    return response
    # 再来研究process_request中直接返回HttpReponse对象,会怎么走接下来的process_response

    # process_view,process_exception,process_template_response
    ```

    ## csrf(跨站请求伪造)

    先写一个简单的post请求,复现报错信息

    钓鱼网站:银行转账的路径,你是否也可以拿到,然后你做一个跟银行一模一样的页面,也超银行的借口提交数据,当用户在钓鱼网站输入对方账户名和转账金额之后,点击发送。其实内部是将对方账户换成了钓鱼网站的造假人员的账户。造成你转账转错账户的情况

    开两个django项目,模拟转账的现象

    如何区分钓鱼网站和正经网站?在正经网站返回页面的时候,在form表单中偷偷塞一个特殊的字符串,后端记下改页面对应的字符串的值,等用户发post请求来的时候,我先去校验特殊的字符串是否匹配

    如何去写这个特殊的字符串呢?模版语法有一个固定的写法{% csrf_token %},必须写在form表单内

    浏览器查看改标签的值,并且每次都在刷新。再来演示刚刚转账的示例

    ajax中如何设置csrf_token

    ```python
    # 第一种页面上先写一个{%csrf_token%}标签,后面用jquery查找标签取值组成键值对放入data中即可
    ```

    csrf_token局部使用

    ```python
    # 只想给某个视图韩式加上csrf校验
    from django.views.decorators.csrf import csrf_exempt,csrf_protect

    # 局部禁用
    @csrf_exempt
    def index(request):
    pass

    # 局部使用
    @csrf_protect
    def login(request):
    pass

    # CBV比较特殊,不能单独加在某个方法上
    # 只能加在类上或dispatch方法上
    from django.utils.decorators import method_decorator
    from django.views.decorators.csrf import csrf_exempt,csrf_protect
    @method_decorator(csrf_exempt,name='get') # 第一种
    class Csrf_Token(View):
    @method_decorator(csrf_exempt) # 第二种
    def dispatch(self,request,*args,**kwargs):
    res = super().dispatch(request,*args,**kwargs)
    return res
    @method_decorator(csrf_exempt) # 这里这么写不行!!!
    def get(self,request):
    pass
    def post(self,request):
    pass
    ```

    # Auth认证模块

    执行数据库迁移的那两条命令时,即使我们没有建表,django是不是也会创建好多张表?我们创建之后去看一下里面的一个叫auth_user表,既然是表,那肯定应该有对应的操作改表的方法

    auth_user表记录的添加

    - 创建超级用户(不可手动插入,因为密码是加密的)

    - 简单使用auth认证

    ```python
    from django.contrib import auth
    def login(request):
    if request.method == 'POST':
    name = request.POST.get('name')
    pwd = request.POST.get('pwd')
    user = auth.authenticate(request,username=name,password=pwd)
    # 类似于user=models.User.objects.filter(username=name,password=pwd).first()
    if user:
    return redirect('/home/')
    return render(request,'login.html')
    ```

    - 只是简单的验证信息不行,还需要给当前成功登陆的用户保存登陆状态,之前是通过cookie或者session,现在呢,auth也给你提供了一个比较好用的方法

    ```python
    if user:
    # 等价于request.session['name']=name
    auth.login(request,user) # 登陆,其实就把用户信息放到session中,跑一下验证session表
    ```

    - 上面的验证和登陆其实不是它的亮点,亮点在于

    ```python
    # 只要登陆成功执行了auth.login(request,user)
    # 之后在其他任意的视图函数中都通过request.user获取当前登陆用户对象

    # 当没有执行auth.login,request.user打印出来的是匿名用户。将session表数据删除即可演示改效果
    # 如何判断request.user用户是否通过auth.login登陆呢?request.user.is_authenticated

    # 为何执行auth.login之后,其他视图函数中就可以通过request.user拿到当前登陆对象呢?想想django的中间件中有没有一个叫Auth啥的中间件,它干了件什么事,能不能推导一下?取出session去表里面查相应的数据,然后放到request.user中,点进去看一下这个中间件确实如此
    ```

    - 注销

    ```python
    auth.logout(request)
    # 等价于删除session数据request.session.flush()
    ```

    - 装饰器校验是否登陆及跳转

    ```python
    from django.contrib.auth.decorators import login_required

    @login_required(login_url='/login/',redirect_field_name='old') # 没登陆会跳转到login页面,并且后面会拼接上你上一次想访问的页面路径/login/?next=/test/,可以通过参数修改next键名
    def my_view(request):
    pass
    ```

    - 如果我所有的视图函数都需要装饰并跳转到login页面,那么我需要写好多份

    ```python
    # 可以在配置文件中指定auth校验登陆不合法统一跳转到某个路径
    LOGIN_URL = '/login/' # 既可以局部配置,也可以全局配置
    ```

    - 回到最上面,我们是怎么对auth_user表添加数据的?命令行输入~~~合理不?

    ```python
    from django.contrib.auth.models import User
    def register(request):
    User.objects.create() # 不能用这个,因为密码是明文
    User.objects.createuser() # 创建普通用户
    User.objects.createsuperuser() # 创建超级用户
    ```

    - 校验密码,修改密码

    ```python
    request.user.check_password(pwd) # 为什么不直接获取查,因为前端用户输入的是明文数据库密文

    request.user.set_password(pwd)
    request.user.save() # 修改密码
    ```

    #### 自定义模型表应用auth功能

    如何扩张auth_user表?

    - 一对一关联(不推荐)

    ```python
    from django.contrib.auth.model s import User

    class UserDetail(models.Models):
    phone = models.CharField(max_length=11)
    user = models.OnoToOneField(to=User)
    ```

    - 面向对象的继承

    ```python
    from django.contrib.auth.models import User,AbstractUser
    class UserInfo(AbstractUser):
    phone = models.CharField(max_length=32)

    # 需要在配置文件中,指定我不再使用默认的auth_user表而是使用我自己创建的Userinfo表
    AUTH_USER_MODEL = "app名.models里面对应的模型表名"


    """
    自定义认证系统默认使用的数据表之后,我们就可以像使用默认的auth_user表那样使用我们的UserInfo表了。
    库里面也没有auth_user表了,原来auth表的操作方法,现在全部用自定义的表均可实现
    """
    ```

    """

    昨日内容回顾
    CBV装饰器
    from django.utils.decorators import method_decorator
    三种方式
    1.在类上面加,需要通过name参数指定被装饰的方法
    @method_decorator(login_auth,name='get')
    2.直接在想装饰方法上
    @method_decorator(login_auth)
    3.重写dispatch,直接给dispatch装(意味着该类中所有的方法都被装饰了)
    @method_decorator(login_auth)

    django中间件
    django的门户/保安
    django暴露给用户可以自定义的无法方法
    需要掌握的:
    process_request:请求来的时候会从上往下依次执行(如果在该方法中返回了一个HttpResponse对象
    那么不再走后续的中间件了会走到用级别的process_response方法依次从下往上返回)
    process_response:响应走的时候会从下往上依次执行(需要将形参的response返回)

    需要了解的:
    process_view:路由匹配成功执行视图函数之前(如果直接返回了一个HttpResponse对象,那么他会从下面最后一个中间件往上依次执行process_response)
    process_exception:视图函数报错了会自动触发(从下往上)
    process_template_response:当返回的对象中一个render方法时(或者包含一个template_response对象)

    自定义中间件
    在响应的应用下创建一个任意的文件夹,该文件夹内建一个任意的py文件
    from django.utils.deprecation import MiddlewareMixin
    class MyMdzz(MiddlewareMixin):
    def process_request(self,request):
    return None

    def process_response(self,request,response):
    return response
    在settings中配置
    '应用名.文件夹名.文件名.类名'

    跨站请求伪造(Csrf)
    form表单中
    {% csrf_token %}

    ajax提交
    # 第一种
    data:{'csrfmiddlewaretoken':$('[name="csrfmiddlewaretoken"]').val()}
    # 第二种
    data:{'csrfmiddlewaretoken':'{{ csrf_token }}'}

    from django.views.decorators.csrf import csrf_exempt,csrf_protect
    from django.utils.decorators import method_decorator

    FBV:
    @csrf_exempt
    def index(request):
    return HttpResponse('index')

    CBV:

    """
    csrf_protect:跟你注册的CBV装饰一样 》》》 三种方法
    csrf_exempt:只能给dispatch这个方法装
    @method_decorator(csrf_exempt,name='dispatch') # 第一种
    class Index3(View):
    # @method_decorator(csrf_exempt) # 第二种
    def dispatch(self, request, *args, **kwargs):
    super().dispatch(request,*args,**kwargs)
    其实都是给dispatch加
    """

    auth模块
    from django.contrib import auth
    创建超级用户
    createsuperuser

    用户相关的功能模块,默认操作的就是auth_user

    # 查询当前用户是否存在(必须传用户名和密码才可以校验用户是否存在)
    # 等价于models.User.objects.filter(**kwargs).first()
    user_obj = auth.authenticate(request,username=username,password=password)
    # 记录当前用户状态
    auth.login(request,user_obj) # 等价于request.session['name'] = user_obj
    """
    只要执行了auth.login(request,user_obj)你就可以在任意的位置通过request.user拿到当前登录对象
    """
    # 退出登录
    auth.logout(request)
    # 修改密码
    request.user.check_password('jason123')
    request.user.set_password('jason666')
    request.user.save()
    # 注册功能
    from django.contrib.auth.models import User
    User.objects.create(**kwargs) # 密码变成明文的 不能用!
    User.objects.create_user(**kwargs)
    User.objects.create_superuser(**kwargs)


    扩展表的字段
    # 第一种方法 一对一关联表
    Class UserDetail(models.Models):
    phone = ...
    avatar = ...
    detail = models.OneToOneField(to='User')

    # 第二种 继承真正的AbstractUser
    class UserInfo(AbstractUser):
    phone = ...
    avatar = ...
    ps:必须在配置文件中告诉django不再用默认的auth_user来支持auth模块了
    AUTH_USER_MODEL = '应用名.表名'
    AUTH_USER_MODEL = 'app01.UserInfo'



    # 装饰器
    from django.contrib.auth.decorators import login_required

    @login_required(login_url='/login/') # 局部配置
    def index(request):
    return HttpResponse('index')

    # 全局配置
    # 配置文件中
    LOGIN_URL = '/login/'




















  • 相关阅读:
    10.19的一些题
    10.18 模拟赛
    bzoj 2212 Tree Rotations
    10.11的一些题
    10.15 模拟赛
    bzoj 5329 战略游戏
    php面向对象基础(二)
    php面向对象基础(一)
    PHP基础-数组与数据结构
    php基础-字符串处理
  • 原文地址:https://www.cnblogs.com/huangxuanya/p/11079634.html
Copyright © 2020-2023  润新知