zoukankan      html  css  js  c++  java
  • Django之中间件及Auth认证模块

    CBV加装饰器

    # 写一个装饰器验证session
    def login_auth(func):
      def inner(request,*args,**kwargs):
        if request.session.get('is_login'):
          return func(request,*args,**kwargs)
       	else:
          return redirect('/login/')
        return inner
    # 写一个类作为网站主页,必须登陆才能访问
    
    # 给里面的get,post方法加装饰器
    class Home(View):
      def get(self,request):
        pass
      def post(self,request):
        pass
      
    # 两种加装饰器的方法
    # 1,类名上面加装饰器
    from django.utils.decoration import method_decorator
    @method_decorator(login_auth,name='get')  # 加在类上面的话,必须通过name指定给谁加
    class Home(View):
      def get(self,request):
        pass
      def post(self,request):
        pass
      def dispatch(self,request):  # name=dispatch时,类中所有方法都加装饰
        pass
    
    # 2,方法上面加,不要用原生的装饰器,用的话,只能改参数,那样的话不通用
    class Home(View):
      @method_decorator(login_auth) 
      def get(self,request):
        pass
      def post(self,request):
        pass
    

    django中间件

    什么是中间件?

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

    中间件能干嘛?

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

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

    自定义中间件

    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
    

    中间件中各个方法的执行顺序

    Django请求流程图

    csrf(跨站请求伪造)

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

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

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

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

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

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

    ajax中如何设置csrf_token

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

    csrf_token局部使用

    # 只想给某个视图韩式加上csrf校验
    from django.views.decorators.csrf import csrf_exempt,csrf_protect
    
    # 局部禁用
    @csrf_exempt
    def index(request):
      pass
    
    # 局部使用
    @csrf_protect
    def login(request):
      pass
    
    
    
    # CBV比较特殊,csrf_exempt不能单独加在某个方法上
    # 只能加在类上或dispatch方法上
    from django.utils.decorators import method_decorator
    from django.views.decorators.csrf import csrf_exempt,csrf_protect
    
    
    @method_decorator(csrf_exempt,name='dispatch')  # 第一种
    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)  # csrf_exempt这么写不行,csrf_protect就可以
      def get(self,request):
        pass
      def post(self,request):
        pass
    

    Auth认证模块

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

    auth的一些方法

    from django.contrib import auth
    # 1.authenticate  过滤符合条件对象
    user_obj = auth.authenticate(request,
                                 username=username,password=password)
    # models.User.objects.filter(username=username,
    #							password=password).first()
    # 2.记录用户状态
    auth.login(request,user_obj)    # 把用户信息放到session中
    # 等价于request.session['name']=name
    # 只要登陆成功执行了auth.login(request,user)
    # 之后在其他任意的视图函数中都通过request.user获取当前登陆用户对象
    # 3.注销
    auth.logout(request)
    # 等价于删除session数据request.session.flush()
    

    简单使用auth认证

    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)
        if user:
          return redirect('/home/')
      return render(request,'login.html')
    

    注意

    # 只要登陆成功执行了auth.login(request,user)
    # 之后在其他任意的视图函数中都通过request.user获取当前登陆用户对象
    # 当没有执行auth.login,request.user打印出来的是匿名用户。
    # 如何判断request.user用户是否通过auth.login登陆呢?request.user.is_auth
    

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

    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
    

    登录认证装饰器的配置

    # 可以在配置文件中指定auth校验登陆不合法统一跳转到某个路径
    LOGIN_URL = '/auth_login/'  # 既可以局部配置,也可以全局配置
    # 上面的'/auth_login/'是登录视图函数所对应的url
    当在settings文件配置上面信息后
    视图中的登录认证装饰器就可以由
    局部配置@login_required(login_url='/auth_login/') 
    换成全局配置@login_required
    

    auth_user表用户添加

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

    request.user对象的密码校验和修改

    request.user.check_password(pwd)  # 校验该密码是否正确 返回bool值
    request.user.set_password(pwd) # 给request.user对象设置新的密码
    request.user.save()  # 将对该对象的密码修改同步到数据库中
    request.user.is_authenticated() # 验证是否登录
    

    自定义模型表应用auth功能

    拓展auth_user表

    • 一对一关联(不推荐)

      from django.contrib.auth.model import User
      
      class UserDetail(models.Models):
        phone = models.CharField(max_length=11)
        user = models.OnoToOneField(to=User)
      
    • 面向对象的继承

      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表的操作方法,现在全部用自定义的表均可实现
      """
      
  • 相关阅读:
    商城----项目宏观(1)
    Java动态代理-JDK自带实现
    git提交出现remote rejected master -> XX changes closed
    openstack认证实践
    转一篇Git代码回滚技巧
    线段树解决leetcode307. Range Sum Query
    The Skyline Problem leetcode 详解
    编程容易犯错的几个地方
    c++中小项堆声明和使用
    C++中int转为char 以及int 转为string和string 转int和字符串的split
  • 原文地址:https://www.cnblogs.com/9527mwz/p/11047120.html
Copyright © 2011-2022 走看看