Cookie和Session、中间件

cookie与session简介

http协议
四大特性
  1.基于请求响应
       2.基于TCP/IP作用于应用层之上
       3.无状态
      基于http协议通信的服务端无法保存客户端状态
          纵使见她千百遍 我都当她如初见
       4.无(短)连接
       
随着互联网的发展 很多网站都需要保存客户端状态 为了实现该需求
cookie与session应运而生(最初的功能核心:保存用户状态)
   cookie:服务端让客户端浏览器保存的数据(kv键值对)  # 保存在服务端(浏览器)
   session:服务端保存的关于用户相关的数据(kv键值对)  # 保存在客户端
   '''session的工作需要依赖于cookie'''
   
# 目前只要是需要用户登录的网站 基本都需要使用cookie
客户端浏览器也可以拒绝保存cookie

django操作cookie

# 视图函数必须返回HttpResponse对象
from django.shortcuts import HttpResonse,render,redirect
return HttpResonse()
return render()
return redirect()

# 要想操作Cookie必须先产生对象 之后利用对象内置方法操作
obj1 = HttpResonse()
return obj1
obj2 = render()
return obj2
obj3 = redirect()
return obj3

# 设置与获取cookie
obj.set_cookie()  # 让浏览器保存cookie数据
request.COOKIES.get()  # 获取浏览器携带过来的cookie数据
obj.set_cookie(max_age/expires)  # 设置失效时间,以秒为基准
obj.delete_cookie()

# 获取用户输入
request.path_info # 用来访问当前用户想要访问的地址(仅仅获取url匹配路径)
request.get_full_path()  # 获取全路径(包括?后面的)


# 登录功能
def login(request):
   if request.method == 'POST':
       request.GET.get('data_get')
       username = request.POST.get('username')
       password = request.POST.get('password')
       if username == 'json' and password == '123':
           data_get = request.GET.get('data_get','/home/')
           obj = redirect(data_get)
           obj.set_cookie('name','jason')
           return obj
       return HttpResponse('用户名或密码错误')
   return render(request,'login.html')

# 添加登录功能的装饰器模板
def loginauthor(func):
   def inner(request,*args,**kwargs):
       data_get = request.path_info
       data = request.COOKIES.get('name')
       if data == 'jason':
           res = func(request,*args,**kwargs)
           return res
       return redirect('/login/?data_get=%s' %data_get)
   return inner

django操作session


request.session[key] = value  # 设置session
# 需要对数据库进行迁移操作(生成一个表用来存放随机字符串与数据的对应关系)
1.django自动产生一个随机字符串
   2.默认在django_session表中保存随机字符串与数据的对应关系
   3.将随机字符串发送给客户端浏览器保存
  sessionid:随机字符串

request.session.get(key)  # 获取session
1.django自动获取浏览器发送过来的cookie数据 获取随机字符串
   2.拿着随机字符串去django_session表中比对
   3.如果对应上了则获取数据并解密成明文的形式

"""django默认的session失效时间>>>:两周(14d)"""
# 删除当前会话的所有Session数据
request.session.delete()  # 只删服务端的,客户端不删
  
# 删除当前的会话数据并删除会话的Cookie。
request.session.flush() # 推荐使用
这用于确保前面的会话数据不可以再次被用户的浏览器访问

# 设置会话Session和Cookie的超时时间
request.session.set_expiry(value)
   * 如果value是个整数,session会在些秒数后失效。
   * 如果value是个datatime或timedelta,session就会在这个时间后失效。
   * 如果value是0,用户关闭浏览器session就会失效。
   * 如果value是None,session会依赖全局session失效策略。
 
# session是存储在服务端的,但存储位置是可以自定义的
1. 数据库Session
SESSION_ENGINE = 'django.contrib.sessions.backends.db'   # 引擎(默认)
2. 缓存Session
SESSION_ENGINE = 'django.contrib.sessions.backends.cache'  # 引擎
SESSION_CACHE_ALIAS = 'default'                            # 使用的缓存别名(默认内存缓存,也可以是memcache),此处别名依赖缓存的设置
3. 文件Session
SESSION_ENGINE = 'django.contrib.sessions.backends.file'    # 引擎
SESSION_FILE_PATH = None                                    # 缓存文件路径,如果为None,则使用tempfile模块获取一个临时地址tempfile.gettempdir()
4. 缓存+数据库
SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'        # 引擎
5. 加密Cookie Session
SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies'   # 引擎
   
   django_session表中的数据个数是取决于浏览器的
   同一个计算机的同一个浏览器只会有一条数据
   主要是为了节省服务端数据库资源
   

CBV添加装饰器的三种方法

路由:url['/MyLogin/',views.MyLogin.as_view()]
'''
CBV中django不建议直接给类的方法添加装饰器,需要借助模块
from django.utils.decorators import method_decorator
'''
# 第一种
from django.utils.decorators import method_decorator
from django.views import View
class MyLogin(View):
   @method_decorator(装饰器名称)
   def get(self,request):
       return HttpResponse('from get')
   def post(self,request):
       return HttpResponse('from post')
# 第二种
在类上面加
@method_decorator(装饰器名称,name=需要加装饰器的方法)  # 可以加多个

from django.utils.decorators import method_decorator
from django.views import View

@method_decorator(mylogin,name=get)
@method_decorator(mylogin,name=post)
class MyLogin(View):
   def get(self,request):
       return HttpResponse('from get')
   def post(self,request):
       return HttpResponse('from post')
   
# 第三种
重写dispatch方法  # 作用于全局(它会直接作用于当前当前类里面的所有方法)
@method_decorator(装饰器名称)
def dispatch(self, request, *args, **kwargs)

from django.utils.decorators import method_decorator
from django.views import View
class MyLogin(View):
   def get(self,request):
       return HttpResponse('from get')
   def post(self,request):
       return HttpResponse('from post')
因为CBV中首先执行的就是dispatch方法,所以这么写相当于给get和post方法都加上了登录校验。

 

什么是django中间件

# 什么是中间件?

   官方的说法:中间件是一个用来处理Django的请求和响应的框架级别的钩子。它是一个轻量、低级别的插件系统,用于在全局范围内改变Django的输入和输出。每个中间件组件都负责做一些特定的功能。

   但是由于其影响的是全局,所以需要谨慎使用,使用不当会影响性能。

   说的直白一点中间件是帮助我们在视图函数执行之前和执行之后都可以做一些额外的操作,它本质上就是一个自定义类,类中定义了几个方法,Django框架会在请求的特定的时间去执行这些方法。

# django中间件类似于django的门户 请求来和走都必须经过它
'''
当我们需要给web后端添加一些全局相关的功能时可以使用中间件
1.校验每个用户的访问频率
2.校验每个用户的登录状态
3.用户黑名单、白名单
4.用户权限
...
'''

如何自定义中间件

# django默认有七个中间件 并且还支持用户自定义中间件
中间件其实是一个个的模块
from django.middleware.security import SecurityMiddleware
MIDDLEWARE = [
   'django.middleware.security.SecurityMiddleware',
   'django.contrib.sessions.middleware.SessionMiddleware', # 与Session相关操作
   'django.middleware.common.CommonMiddleware',
   'django.middleware.csrf.CsrfViewMiddleware',
   'django.contrib.auth.middleware.AuthenticationMiddleware',
   'django.contrib.messages.middleware.MessageMiddleware',
   'django.middleware.clickjacking.XFrameOptionsMiddleware',
   'middlewares.MD1',  # 自定义中间件MD1
   'middlewares.MD2'  # 自定义中间件MD2
]

自定义中间件我们可以编写五个方法(我们可以在自定义中间件中校验每个用户的访问频率等等)

def process_request(self,request)
def process_response(self,request,response)
process_template_response(self,request,response)
process_exception(self, request, exception)
process_view(self, request, view_func, view_args, view_kwargs)

# 自定义创建中间件
'''
1.在项目名或者应用下创建一个任意名称的文件夹
2.在该文件夹内创建一个任意文件的py文件
3.在该文件内需要书写类(这个类必须继承MiddlewareMixin)
然后再这个类里就可以自定义5个方法了
(这5个方法并不是全部需要书写,用几个写几个)
4.需要将类的路径以字符串的形式注册到配置文件中才能够生效
'''

# 必须掌握的方法
   1、process_request(self,request) # 每一个进来的数据都需要先经过process_request方法
       1.当请求来的时候会从上往下依次执行每一个中间件里面的该方法
       如果没有则直接下一个
       2.当该方法返回了HttpResponse对象 那么请求不再继续往后执行
       而是直接原路返回(相当于验证失败)
           
'''
中间件的process_request方法是在执行视图函数之前执行的。
当配置多个中间件时,会按照MIDDLEWARE中的注册顺序,也就是列表的索引值,从前到后依次执行的。
不同中间件之间传递的request都是同一个对象
'''
   2、process_response(self,request,response)  # 请求返回时走该方法
       1.当响应返回的时候会从下往上依次执行每一个中间件里面的该方法
       如果没有则直接下一个 该方法默认要返回response
       2.该方法返回什么浏览器就会接收到什么(也就意味着我们可以中途拦截待返回的数据做其他处理)
       # process_request方法如果直接返回HttpResonse对象则直接执行process_response原理返回
       
需要了解的方法
   process_view
  路由匹配成功之后执行视图函数之前自动触发
   process_template_response
  当返回的对象中含有render属性自动触发
   process_exception
  当视图函数报错之后会自动触发

 

 

posted @ 2021-12-07 19:40  一叶松  阅读(174)  评论(0编辑  收藏  举报