django操作cookie补充,django操作session,CBV添加装饰器,django中间件,自定义中间件

django操作cookie补充

set_signed_cookie(key,value,salt='加密盐')
set_signed_cookie(key,value,max_age=超时时间:默认是秒数)
expires:专门针对IE浏览器设置超时时间
  
#删除cookie
HttpResponse对象.delete_cookie(key) 

django操作session

# 设置
request.session['key'] = value  # 可以设置多组
# 获取
request.session.get('key')  # 可以获取多组
"""
服务端保存用户相关状态信息 返回给客户端随机字符串
针对保存 django需要一张表来处理 >>> 自带的django_session表
ps:django数据库迁移命令会产生一堆默认的表 其中就有一张django_session表
"""

基本操作

以键值对的格式写 session request.session['键']=值

根据键读取值 request.session.get('键',默认值) # 或者 request.session['键'] 

清除所有 session,在存储中删除值的部分 request.session.clear() 清除 session 数据,

在存储中删除 session 的整条数据 request.session.flush() 删除 session 中的指定键及值,

在存储中只删除某个键及对应的值 del request.session['键'] 

设置 session 数据有效时间; 如果不设置,默认过期时间为两周 request.session.set_expiry(value)
  如果过期时间的 value 是一个整数,则 session 数据 将在 value 秒没有活动后过期。
  如果过期时间的 value 为 None,那么会话永不过期。
  如果过期时间的 value 为 0,那么用户会话的 Cookie 将在用户的浏览器关闭时过期。

CBV添加装饰器

'''需要借助于一个专门的装饰器模块'''
from django.utils.decorators import method_decorator

装饰器

# 装饰器
def login_auth(func):
    def inner(request, *args, **kwargs):
        if request.session.get("is_login"):
            res = func(*args, **kwargs)
            return res
        else:
            return redirect('/login/')
    return inner

第一种---直接在类中的某个方法上添加

class Index(View):
    # 在每个需要验证的地方都加上装饰器
    @method_decorator(login_auth)
    def get(self, request):
        print("get 请求")
        return render(request, "index.html")
    @method_decorator(login_auth)
    def post(self, request):
        print("post 请求")
        return HttpResponse("post")

第二种---在类的上面加上,name为具体要加的函数

@method_decorator(login_auth, name='post')
@method_decorator(login_auth, name='get')
class Index(View):
    def get(self, request):
        print("get 请求")
        return render(request, "index.html")
    def post(self, request):
        print("post 请求")
        return HttpResponse("post")

第三种---重写dispatch方法并添加作用于类中所有的方法

class Index(View):
    #方法三  使用dispatch给所有的方法添加装饰器
    @method_decorator(login_auth)
    def dispatch(self, request, *args, **kwargs):
        return super().dispatch(request, *args, **kwargs)
    def get(self, request):
        print("get 请求")
        return render(request, "index.html")
    def post(self, request):
        print("post 请求")
        return HttpResponse("post")

django中间件

什么是中间件

  中间件,是介于request与response处理之间的一道处理过程,相对比较轻量级,并且在全局上改变django的输入与输出
  由于它影响的是全局,所以需要谨慎使用,用不好会影响到性能
'''
  如果你想修改请求,例如被传送到view中的HTTPResponse对象,或者你想修改HttpResponse对象,这些都可以通过中间件实现
  如果你还想在view执行之前做一些操作,这种情况就可以用middleware来实现
'''

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',
]

自定义中间件

步骤

1.创建一个任意名称的文件夹
2.在该文件夹内创建一个任意名称的py文件,并在该 py 文件中导入 MiddlewareMixin。
  '''from django.utils.deprecation import MiddlewareMixin'''
3.在该py文件内编写中间件类,要继承父类 MiddlewareMixin
  class MD1(MiddlewareMixin): 
    pass
4.在 settings.py 中的 MIDDLEWARE 里注册自定义的中间件类:
  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',
     
      'app01.middlewares.MD1',
  ]

自定义中间件类的方法:process_request 和 process_response

process_request 方法

process_request 方法有一个参数 request,这个 request 和视图函数中的 request 是一样的。

process_request 方法的返回值可以是 None 也可以是 HttpResponse 对象。

    返回值是 None 的话,按正常流程继续走,交给下一个中间件处理。
    返回值是 HttpResponse 对象,Django 将不执行后续视图函数之前执行的方法以及视图函数,直接以该中间件为起点,倒序执行中间件,且执行的是视图函数之后执行的方法。

process_request 方法是在视图函数之前执行的。

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

不同中间件之间传递的 request 参数都是同一个请求对象。
'''
from django.utils.deprecation import MiddlewareMixin

from django.shortcuts import render, HttpResponse

class MD1(MiddlewareMixin):
    def process_request(self, request):
       print("md1  process_request 方法。", id(request)) #在视图之前执行
'''

process_response方法

process_response 方法有两个参数,一个是 request,一个是 response,request 是请求对象,response 是视图函数返回的 HttpResponse 对象,该方法必须要有返回值,且必须是response。

process_response 方法是在视图函数之后执行的。

当配置多个中间件时,会按照 MIDDLEWARE 中的注册顺序,也就是列表的索引值,倒序执行。
'''
class MD1(MiddlewareMixin):
    def process_request(self, request):
        print("md1  process_request 方法。", id(request)) #在视图之前执行


    def process_response(self,request, response): :#基于请求响应
        print("md1  process_response 方法!", id(request)) #在视图之后
        return response
'''

正常的情况下按照绿色的路线进行执行,假设中间件1有返回值,则按照红色的路线走,直接执行该类下的 process_response 方法返回,后面的其他中间件就不会执行。

process_view方法

process_view 方法格式如下:
  process_view(request, view_func, view_args, view_kwargs)

process_view 方法有四个参数:
  request 是 HttpRequest 对象。
  view_func 是 Django 即将使用的视图函数。
  view_args 是将传递给视图的位置参数的列表。
  view_kwargs 是将传递给视图的关键字参数的字典。

view_args 和 view_kwargs 都不包含第一个视图参数(request)。

process_view 方法是在视图函数之前,process_request 方法之后执行的。

返回值可以是 None、view_func(request) 或 HttpResponse 对象。

    返回值是 None 的话,按正常流程继续走,交给下一个中间件处理。
    返回值是 HttpResponse 对象,Django 将不执行后续视图函数之前执行的方法以及视图函
数,直接以该中间件为起点,倒序执行中间件,且执行的是视图函数之后执行的方法。
    返回值是 view_func(request),Django 将不执行后续视图函数之前执行的方法,提前执行视
图函数,然后再倒序执行视图函数之后执行的方法。
    当最后一个中间件的 process_request 到达路由关系映射之后,返回到第一个中间件 
process_view,然后依次往下,到达视图函数。
'''
class MD1(MiddlewareMixin):
    def process_request(self, request):
        print("md1  process_request 方法。", id(request)) #在视图之前执行


    def process_response(self,request, response): :#基于请求响应
        print("md1  process_response 方法!", id(request)) #在视图之后
        return response


    def process_view(self,request, view_func, view_args, view_kwargs):
        print("md1  process_view 方法!") #在视图之前执行 顺序执行
        #return view_func(request)
'''

process_exception方法

process_exception 方法如下:
  process_exception(request, exception)

参数说明:
  request 是 HttpRequest 对象。
  exception 是视图函数异常产生的 Exception 对象。

process_exception 方法只有在视图函数中出现异常了才执行,按照 settings 的注册倒序执行。

在视图函数之后,在 process_response 方法之前执行。

process_exception 方法的返回值可以是一个 None 也可以是一个 HttpResponse 对象。

  返回值是 None,页面会报 500 状态码错误,视图函数不会执行。
  process_exception 方法倒序执行,然后再倒序执行 process_response 方法。

  返回值是 HttpResponse 对象,页面不会报错,返回状态码为 200。
  视图函数不执行,该中间件后续的 process_exception 方法也不执行,直接从最后
一个中间件的 process_response 方法倒序开始执行。

若是 process_view 方法返回视图函数,提前执行了视图函数,且视图函数报错,则无论 
process_exception 方法的返回值是什么,页面都会报错, 且视图函数和 process_exception 方法都不执行。

直接从最后一个中间件的 process_response 方法开始倒序执行:
'''
class MD1(MiddlewareMixin):
    def process_request(self, request):
        print("md1  process_request 方法。", id(request)) #在视图之前执行

    def process_response(self,request, response): :#基于请求响应
        print("md1  process_response 方法!", id(request)) #在视图之后
        return response

    def process_view(self,request, view_func, view_args, view_kwargs):
        print("md1  process_view 方法!") #在视图之前执行 顺序执行
        #return view_func(request)


    def process_exception(self, request, exception):#引发错误 才会触发这个方法
        print("md1  process_exception 方法!")
        # return HttpResponse(exception) #返回错误信息
'''

process_template_response(很少用)

    视图函数执行完毕之后返回的对象中含有render属性对应一个render方法
    则会从下往上执行配置文件中注册了的中间件里面的process_template_response方法
'''
def index(request):
    print('视图函数:index')
    def render():
        return HttpResponse('很奇葩')
    res = HttpResponse("视图函数:index")
    res.render = render
    return res
'''

CSRF跨站点请求伪造

    CSRF跨站点请求伪造(Cross—Site Request Forgery):大概可以理解为攻击者盗用了你的身
    份,以你的名义在恶意网站发送恶意请求,对服务器来说这个请求是完全合法的,但是却完成了攻击
    者所期望的一个操作,比如以你的名义发送邮件、发消息,盗取你的账号,甚至于购买商品、转账等。

csrf解决策略

# form表单
	<form action="" method="post">
    {% csrf_token %}
    <p>当前账户:<input type="text" name="current_user"></p>
    <p>目标账户:<input type="text" name="target_user"></p>
    <p>转账金额:<input type="text" name="money"></p>
    <input type="submit">
	</form>

# ajax请求
  1.方式1:页面任意位置先写{% csrf_token %} 之后获取数据     'csrfmiddlewaretoken':$('input[name="csrfmiddlewaretoken"]').val()
  2.方式2:模板语法直接获取
    'csrfmiddlewaretoken':{{ csrf_token }}
  '''
      <script>
          $('#d1').click(function () {
              $.ajax({
                  url:'',
                  type:'post',
                  data:{
                      'current_user':$('input[name="current_user"]').val(),
                      'target_user':$('input[name="target_user"]').val(),
                      'money':$('input[name="money"]').val(),
                      {#'csrfmiddlewaretoken':$('input[name="csrfmiddlewaretoken"]').val()#}
                      {#'csrfmiddlewaretoken':{{ csrf_token }}#}
                  },
                  success:function (args) {
                      alert(args)
                  }
              })
          })
      </script>
  '''

通用方法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);
      }
    }
  });
'''也只能适用于ajax提交  form表单还是需要额外指定'''
posted @ 2022-05-24 21:30  春游去动物园  阅读(42)  评论(0编辑  收藏  举报