zoukankan      html  css  js  c++  java
  • cookie与session django中间件

    一、什么是cookie

    1、由于BS架构基于HTTP协议,是无状态的,不能保存客户端状态

    2、使用cookie/session技术可以保存客户端用户状态

    3、cookie是服务端生成发送给客户端的键值对,浏览器会保存它

    4、浏览器可以设置禁止cookie的写入,即不保存cookie

    二、django中操作cookie

    2.1 如何操作cookie

    视图函数都是返回一个对象,只需要给这个对象进行操作就可以了

    # 一般有三种方式返回数据
    obj = HttpResponse()
    return obj
    
    obj = render()
    return obj
    
    obj = redirect()
    return obj
    

    2.2 操作cookie

    1、生成cookie

    # 生成cookie
    obj.set_cookie('k1','v1',max_age=3)
    obj.set_cookie('k1','v1',expires=3)
    '''
    1、客户端接收到的数据为键值对 k1:v1
    2、参数max_age与expires都是设置cookies的有效时间,区别在于,当客户端为IE浏览器时,只能用expires
    '''
    

    2、服务端获取cookie

    request.COOKIES.get('k1')  # 获取cookie值
    

    3、删除cookie

    obj.delete_cookie('k1')
    
    '''
    删除cookie意味着注销客户端用户
    定义注销视图函数即可'''
    def logout(request):
        obj = redirect('/login/')
        obj.delete_cookie('user')
    

    三、什么是session

    1、在服务端基于cookie保存客户端状态的数据,一般存储在数据库中

    2、每一个客户端的cookie分配唯一的一个id

    四、django中操作session

    4.1 创建cookie_session表

    1、在django项目第一次创建表,迁移同步到数据库中时,会默认创建多个表,其中包括diango_sessioon表

    2、在django_session表创建完成的情况下,才能操作session

    4.2 操作session

    1、设置session

    request.session['k1'] = 'v1'
    '''
    1、使用的k1:v1键值对,是生成cookie的相同的键值对
    2、django内部自动调用算法生成一个随机的字符串
    3、django_session表中添加数据
        以2中生成的字符串为主键session_key
        给数据加密生成字符串,添加进session表中session_data
        同时,自动生成session有效期限,mysql默认为14天  
    '''
    

    2、获取session

    request.session.get('k1')
    '''
    1、django内部会自动去请求头里面获取cookie
    2、拿着session所对应的 随机字符串去django_session表中以一比对session_key
    3、如果比对上了,获取对应的session_data,放入request.session中,以供程序员调用
    4、如果没有比对上,那么request.session就是一个空字典
    '''
    

    3、删除session

    request.session.delete()
    '''
    1、一个客户端对应django_session表中的一条数据
    2、删除session,就是将该客户端对应的所有cookie删除
    '''
    

    4、设置失效时间

    request.session.set_expiry(value)
    '''
    1、value是个整数,时间单位是秒
    2、value是个datatime或者timedelta,那就是最后的有效期
    3、value是0,用户关闭浏览器就会 失效
    4、value是None,session会依赖全局session失效策略
    '''
    

    五、示例:登陆认证

    1、校验cookie/session

    2、验证不通过,重新登陆后自动跳转本来想要访问的页面

    3、使用CBV模式

    def login_auth(func):
        def inner(request, *args, **kwargs):
            next_url = request.get_full_path()
            print(next_url)
            print(request.session.get('username'))
            if request.session.get('username'):
                return func(request, *args, **kwargs)
            else:
                return redirect('/app01/login/%s/' % next_url)
    
        return inner
    
    
    class MyLogin(View):
        def get(self, request):
            return render(request, 'login.html')
    
        def post(self, request):
            username = request.POST.get('username')
            password = request.POST.get('password')
            user_obj = models.User.objects.filter(username=username, password=password)
            if not user_obj:
                return render(request, 'login.html')
    
            request.session['username'] = username
    
            url = reverse('home', kwargs={'username': username})
            obj = redirect(url)
            obj.set_cookie('username', username)
            return obj
    
    
    class MyHome(View):
        @method_decorator(login_auth)
        def get(self, request, username):
            return render(request, 'home.html', {'username': username})
            pass
    
        def post(self, requeest, username):
            pass
    

    六、什么是中间件

    1. 中间件是一个用来处理Django的请求和响应的框架级别的钩子,本质上是一个自定义类
    2. 可以全局范围内在视图函数执行前和施行后做一些额外的操作,比如用户登录校验、用户访问频率校验、用户权限校验
    3. Django中默认有七个中间件
    # settings.py文件
    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. 方法中参数request:必需参数,和视图函数中request一样
    3. 方法中返回值为None时, 继续按照django定义的规则向后继续执行
    4. 方法中返回值为HttpResponse对象时, 则直接将该对象返回给用户
    # 在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.mymiddleware.mymidd.MyMidd1',  # 自定义中间件MD1
        'app01.mymiddleware.mymidd.MyMidd2'  # 自定义中间件MD2
    ]
    

    7.1 process_request

    1. 默认按照自上而下的顺序执行MIDDLEWARE中每一个中间件内部的process_request方法
    2. 返回HttpResponse对象:请求会立刻停止从当前中间件的process_response 方法原路返回
    # app01/mymiddleware/mymidd.py
    
    from django.utils.deprecation import MiddlewareMixin
    
    class MD1(MiddlewareMixin):
        def process_request(self, request):
            print("MD1里面的 process_request")
    
    
    class MD2(MiddlewareMixin):
        def process_request(self, request):
            print("MD2里面的 process_request")
            pass
    

    7.2 process_response

    1. 在视图函数之后 ,默认按照自下而上的顺序执行每个中间件中的process_response 方法
    2. 必须给方法传入两个形参,request和response
    3. 必须返回response:response是视图函数返回的HttpResponse对象 ,浏览器才能接受HttpResponse对象
    # app01/mymiddleware/mymidd.py
    
    from django.utils.deprecation import MiddlewareMixin
    
    class MD1(MiddlewareMixin):
        def process_request(self, request):
            print("MD1里面的 process_request")
    
        def process_response(self, request, response):
            print("MD1里面的 process_response")
            return response
    
    
    class MD2(MiddlewareMixin):
        def process_request(self, request):
            print("MD2里面的 process_request")
            pass
    
        def process_response(self, request, response):
            print("MD2里面的 process_response")
            return response
    

    7.3 process_view

    1. 执行视图函数之前触发(路由匹配之后)
    2. 返回 HttpResponse对象 : 直接在中间件中掉头,倒叙执行一个个process_response方法,最后返回给浏览器
    3. 该方法有四个参数
      1. request: HttpRequest对象
      2. view_func:Django即将使用的视图函数对象
      3. view_args:将传递给视图的位置参数的列表.
      4. view_kwargs是将传递给视图的关键字参数的字典 (不包括request)
    # app01/mymiddleware/mymidd.py
    from django.utils.deprecation import MiddlewareMixin
    
    class MD1(MiddlewareMixin):
        def process_request(self, request):
            print("MD1里面的 process_request")
    
        def process_response(self, request, response):
            print("MD1里面的 process_response")
            return response
    
        def process_view(self, request, view_func, view_args, view_kwargs):
            print("-" * 80)
            print("MD1 中的process_view")
            print(view_func, view_func.__name__)
    
    
    class MD2(MiddlewareMixin):
        def process_request(self, request):
            print("MD2里面的 process_request")
            pass
    
        def process_response(self, request, response):
            print("MD2里面的 process_response")
            return response
    
        def process_view(self, request, view_func, view_args, view_kwargs):
            print("-" * 80)
            print("MD2 中的process_view")
            print(view_func, view_func.__name__)
    

    7.4 process_exception

    1. 视图函数出现错误异常自动触发,按照从下往上的顺序执行
    2. 两个参数 request 和 exception ( 视图函数异常产生的Exception对象 )
    3. 返回 HttpResponse对象 : 调用模板和中间件中的process_response方法,并返回给浏览器 (不会再执行process_exception 方法)

    7.5 process_template_response

    1. 视图函数执行完成后, 视图函数返回的对象有一个render()方法时才会执行,倒序执行
    2. 两个参数 request 和 response ,即必须返回response

    7.6 中间件执行流程

    1. 请求到达中间件, 先按照正序执行每个中间件的process_request方法 ,执行完后匹配路由
    2. 再顺序执行中间件中的process_view方法 ,执行完后执行视图函数
    3. 如果视图函数中有异常,会倒序执行process_exception
    4. 如果视图函数中返回对象有一个render()方法,会倒序执行process_exception方法
    5. 否则,会倒序执行process_response 方法,将响应发给客户端
    • 方法中有response参数的必须返回response(process_template_response、process_response )
    • 方法中没有response参数的(process_view、process_exception、process_response )
      1. 返回none:正常执行
      2. 返回HttpResponse的:会从当前中间件的response方法依次倒序执行,最终发送给客户端

    以上,process_request、process_view默认为顺序,process_exception、process_exception、process_response 默认为倒序

  • 相关阅读:
    mysql 常用函数
    JSP 分页代码
    day15(Mysql学习)
    day14(编码实战-用户登录注册)
    Bootstrap第3天
    Bootstrap第2天
    Bootstrap 第一天
    day13(JSTL和自定义标签&MVC模型&javaweb三层框架)
    label 对齐
    Alert提示框之后跳转指定页面
  • 原文地址:https://www.cnblogs.com/1012zlb/p/12005955.html
Copyright © 2011-2022 走看看