cookie与cession简介

"""
HTTP协议四大特性
	1.基于请求响应
	2.基于TCP、IP作用于应用层之上协议	
	3.无状态
		服务端无法识别客户端的状态
			1.互联网刚开始兴起的的时候 所有人访问网址都是一样的数据
				服务端无法识别客户端问题不大
			2.互联网发展 淘宝、京东、阿里
				服务端不得不想办法记住客户端的状态
				cookie与session应运而生
	4.无连接
"""
Cookie
	保存在客户端上跟用户信息(状态)相关的数据	
Session
	保存在服务端上跟用户信息(状态)相关的数据
ps:session的工作需要依赖于cookie 就算是目前所有能够识别用户身份的网址也都需要使用cookie(客户端浏览器也有权拒绝保存cookie)

django操作cookie

如果想要让客户端浏览器保存cookie需要HttpResonse对象调用方法

return HttpResponse()
return render()
return redirect()
return JsonRepsonse()

经过上次研究源码发现都上诉四个方法最后都是返回一个HttpResponse对象
设置cookie需要变形
obj = HttpResponse()
obj.操作cookie的方法
return obj

1.登录设置cookie
2.多个视图函数都需要校验用户是否登录
	装饰器
3.如何记住用户登录之前想要访问的页面 用户登录成功之后自动跳转
	场景1:用户访问了其他需要登录才可以访问的页面   如何跳转>>>:想要访问的
 	场景2:用户直接访问的登录页面  如何跳转>>>:网址首页
	print(request.path)  # 获取网址后缀
    	print(request.path_info)  # 获取网址后缀
    	print(request.get_full_path())  # 获取网址后缀携带的数据也能获取
代码实现
def login_auto(func_name):
    def inner(request,*args,**kwargs):
        if request.COOKIES.get('name'):
            res = func_name(args,**kwargs)
            return res
        else:
            target_path = request.get_full_path_info()
            return redirect(f'/login/?next={target_path}')
    return inner

def set_cookie(request):
    obj = HttpResponse('中秋快乐鸭')
    obj.set_cookie('name', 'jason')
    return obj


def login(request):
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        if username == 'jason' and password == '123':
            target_path = request.GET.get('next')  # 如果有值则跳到指定页面
            if target_path:
                obj = redirect(target_path)  # 如果没有值则跳转到首页
            else:
                obj = redirect('/home/')  # home作为主页
            obj.set_cookie('name', 'jason')
            return obj
    return render(request, 'login.html')

@login_auto
def home(request):
    # if request.COOKIES.get('name'):
        return HttpResponse('home页面 登录用户才能查看')
    # return redirect('/login/')

@login_auto
def index(request):
    # if request.COOKIES.get('name'):
        return HttpResponse('index页面 登录用户才能查看')
    # return redirect('/login/')

diango操作cession

请求来之后服务端产生随机字符串并发送给客户端保存 服务端存储随机字符串与用户信息的对应关系 之后客户端携带随机字符串 服务自动校验
""""
服务端保存用户相关状态信息 返回给客户端随机字符串
针对保存 django需要一张表来处理>>>:自带的django_session表
    需要执行同步/迁移命令产生一张 django_session表
"""
1.django默认的sessisn失效时间是14天(可人为修改)
2.客户端会接收到键值对 键默认是sessionid值是加密的随机字符串(令牌)

设置
request.session['key'] = 'values'
	1.django自动产生一个随机字符串返回给客户端(对key加密)
	2.往django_session创建数据(对values加密)
获取
request.session.get('key')
	1.自动从django请求回去的sessionid对应的随机字符串
	2.拿着随机字符串去django_session中匹配数据
	3.如果匹配上还会自动解密数据并展示
session的存储位置可以有五种模式
1.数据库
2.缓存数据库
3.文件
4.缓存+数据库
5.加密
session其他操作
1.删除当前会话所有的Session数据
	request.session.delete()
2.删除当前会话数据并删除会话的Cookie
	request.session.flush()
3.设置会话Session和Cookie的超时时间
	request.session.set_expiry(value)
		如果valus是个整数 session会在这些秒数后消失
		如果value是个datatime或timedelta session就会在这个时间后失效
		如果value是0 用户关闭浏览器session就会失效
		如果value是None 失效时间就取决于django内部全局session默认的失效时间(默认14天)

django中间件

django中间件类似于django的门户 所有的请求来和响应都必须经过中间件
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',
    ]
    
django中间件除了默认的之外 还支持自定义中间件(无限)
django中间件使用场景
	全局相关的功能
		全局用户身份校验 全局用户黑名单校验 全局用户访问频率校验

django自定义中间件中可以有五个方法

"""
process_request
process_response
process_view
process_template_response
process_exception
"""
1.在项目名或者应用名下创建一个任意名称的文件夹
2.在该文件夹内创建一个任意名称的py文件
3.在该py文件内需要书写类(这个类必须继承MiddlewareMixin)
	然后在这个类里面就可以自定义五个方法了
	这五个方法并不是全部都需要书写 用几个写几个
4.需要将类的路径以字符串的形式注册到配置文件中才能生效
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',
    '自己写的中间件的路径3',
]

1.process_request
配置文件
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.utils.mymdd.MyMdd1',
    'app01.utils.mymdd.MyMdd2'
]

中间件
from django.utils.deprecation import MiddlewareMixin

class MyMdd1(MiddlewareMixin):
    def process_request(self,request):
        print('MyMdd1 process_request')

class MyMdd2(MiddlewareMixin):
    def process_request(self,request):
        print('MyMdd2 process_request')

视图
def get_md(request):
    print('from get_md')
    return HttpResponse('get md')

"""
执行结果
	MyMdd1 process_request
	MyMdd2 process_request
	from get_md
页面展示
	get md
"""
1.请求来的时候会按照配置文件中注册了的中间件 从上往下依次执行每一个中间件里面的process_request方法 如果没有则直接跳过

2.该方法如果返回了HttpResonse对象 那么请求不会再往后执行 原路返回

class MyMdd1(MiddlewareMixin):
    def process_request(self,request):
        print('MyMdd1 process_request')
        return HttpResponse('半路打劫')

class MyMdd2(MiddlewareMixin):
    def process_request(self,request):
        print('MyMdd2 process_request')
"""
执行结果
	MyMdd1 process_request
页面展示
	半路打劫
"""
2.process_response
配置文件
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.utils.mymdd.MyMdd1',
    'app01.utils.mymdd.MyMdd2'
]

中间件
class MyMdd1(MiddlewareMixin):
    def process_request(self,request):
        print('MyMdd1 process_request')
    def process_response(self,request,response):  # 这个方法需要两个形参
        print('MyMdd1 process_request')
        return response  # 有response必须要返回

class MyMdd2(MiddlewareMixin):
    def process_request(self,request):
        print('MyMdd2 process_request')
    def process_response(self,request,response):  # 这个方法需要两个形参
        print('MyMdd2 process_request')
        return response  # 有response必须要返回

视图
def get_md(request):
    print('from get_md')
    return HttpResponse('get md')

"""
执行结果
	MyMdd1 process_request
	MyMdd2 process_request
	from get_ma
	MyMdd2 process_request
	MyMdd1 process_request
页面展示
	get md
"""

1.响应走的时候会按照配置文件中注册了的中间件 从下往上一次执行每一个中间件里面的process_response方法 没有没有则直接跳过

2.该方法有两个形参request和response 并且默认情况下应该返回response

3.该方法也可以自己返回HttpResponse对象 相当于狸猫换太子
class MyMdd1(MiddlewareMixin):
    def process_request(self, request):
        print('MyMdd1 process_request')
    def process_response(self, request, response):
        print('MyMdd1 process_response')
        return HttpResponse('狸猫换太子')
class MyMdd2(MiddlewareMixin):
    def process_request(self, request):
        print('MyMdd2 process_request')
    def process_response(self, request, response):
        print('MyMdd2 process_response')
        return response
"""
执行结果
	MyMdd1 process_request
	MyMdd2 process_request
	from get_ma
	MyMdd2 process_request
	MyMdd1 process_request
页面展示
	狸猫换太子
"""
ps:如果请求的过程中process_request方法直接反回了HttpResponse对象那么会原地执行同级别process_response方法返回(flask则不同)
class MyMdd1(MiddlewareMixin):
    def process_request(self, request):
        print('MyMdd1 process_request')
        return HttpResponse('猜猜我是谁')
    def process_response(self, request, response):
        print('MyMdd1 process_response')
        return response
class MyMdd2(MiddlewareMixin):
    def process_request(self, request):
        print('MyMdd2 process_request')
    def process_response(self, request, response):
        print('MyMdd2 process_response')
        return response
def get_md(request):
    print('from get_md')
    return HttpResponse("get md")
"""
执行结果
	MyMdd1 process_request
	MyMdd1 process_response
页面展示
	get md
"""
3.process_view

当路由匹配成功之后 执行视图函数之前 自动触发

class MyMdd1(MiddlewareMixin):
    def process_request(self, request):
        print('MyMdd1 process_request')
    def process_response(self, request, response):
        print('MyMdd1 process_response')
        return response
    def process_view(self, request, view_func, view_args, view_kwargs):
        print('MyMdd1 process_view')
class MyMdd2(MiddlewareMixin):
    def process_request(self, request):
        print('MyMdd2 process_request')

    def process_response(self, request, response):
        print('MyMdd2 process_response')
        return response

    def process_view(self, request, view_func, view_args, view_kwargs):
        print('MyMdd2 process_view')
# 视图函数
def get_md(request):
    print('from get md')
    return HttpResponse("get md")
"""
执行结果
	MyMdd1 process_request
	MyMdd2 process_request
	MyMdd1 process_view
	MyMdd2 process_view
	from get_md
	MyMdd2 process_response
	MyMdd1 process_response
页面上展示:
	get md
"""
4.process_excption

当视图函数报错之后 自动触发

def process_excption(request,exception):
    print(exception)  # exception就是报错的具体信息
    print('MyMdd1 process_excption')
5.process_template_response

当视图函数返回的数据对象中含有render属性对应render函数才会触发

def get_md(request):
    print('from get_md')
    def render():
        return HttpResponse("哈哈哈")
    obj = HttpResponse('嘿嘿嘿')
    obj.render = render
    return obj
 posted on 2022-09-12 19:52  Joker_Ly  阅读(52)  评论(0)    收藏  举报