12.4 cookies\sessions

  • cookie :保存在客户端(浏览器)上的键值对,由服务端设置,浏览器有权禁止cookie写入

  • session:保存在服务端(服务器)上的键值对,需要依赖cookie

为什么会有这些技术?

  • 目的是为了保存客户端的用户状态
  • 因为HTTP协议是无状态的

django如何操作cookie

小白必会三板斧
obj=Httpresponse()  #利用obj对象才可以操作cookie
return obj
obj=render()
return obj
obj=redirect()
return obj
如何设置cookie
 obj.set_cookie('k1','v1')   #让浏览器设置键值对

如何获取cookie
 request.COOKIES.get('k1')  #获取浏览器携带过来的cookie值
如何设置cookie的超时时间
  obj.set_cookie('k1','v1',max_age=3)
  obj.set_cookie('k1','v1',expires=3)
两个参数都是设置超时时间 并且都是以秒为单位
区别:如果要给IE浏览器设置cookie的超时时间 只能用expires
如何删除cookie(注销退出登录)
obj.delete_cookie('k1')
def login(request):
    if request.method=='POST':
        username=request.POST.get('username')
        password=request.POST.get('password')
        if username=='ldd' and password=='123':
            #登录成功
            obj=redirect('/home/')
            obj.set_cookie('whoami','ldd',max_age=5)  #告诉浏览器保存一个键值对
            return obj
    return render(request,'login.html')

def home(request):
    #校验用户是否登录
    if request.COOKIES.get('whoami'):
        return HttpResponse('只有登录的用户才能访问')
    return redirect('/login/')

基于cookie实现的登录认证

from django.shortcuts import render,HttpResponse,redirect

# Create your views here.
def login(request):
    if request.method=='POST':
        username=request.POST.get('username')
        password=request.POST.get('password')
        if username=='ldd' and password=='123':
            #登录成功
            old_path=request.GET.get('next')  #用户下次想要访问的路径
            if old_path:  #防止用户直接访问的登录页面根本没有想访问的页面
                obj=redirect(old_path)
            else:
                obj=redirect('/home/') #如果真没有 ,直接跳到首页
            obj.set_cookie('whoami','ldd')  #告诉浏览器保存一个键值对
            return obj 
    return render(request,'login.html')

from functools import wraps
def login_auth(func):
    @wraps(func)
    def inner(request,*args,**kwargs):
        # 校验用户是否登录
        if request.COOKIES.get('whoami'):
            res=func(request,*args,**kwargs)
            return res
        else:
            target_path=request.path_info  #绝对路径 得到url
            return redirect('/login/?next=%s'%target_path)
    return inner

@login_auth
def home(request):
     return HttpResponse('只有登录的用户才能访问')


@login_auth
def index(request):
     return HttpResponse('index页面 也需要登录的用户才能访问')

@login_auth
def home(request):
     return HttpResponse('reg页面 也需要登录的用户才能访问')

@login_auth
def logout(request):
    obj=redirect('/login/')
    obj.delete_cookie('whoami')
    return obj

django如何操作session

#设置session
request.session['k1']='v1'
第一次设置的时候会报错 是因为没有执行数据库迁移命令 生成django需要用到一些默认表(django_session)  django默认的失效时间是14天 2周

'''
request.session['k1']='v1'
'''
这句话到底发生了哪些事
1.django内部自动帮你调用算法生成一个随机的字符串
2.在django_session添加数据(数据也是加密处理)
  随机字符串    加密之后的数据  失效时间
    sjhhdj          gdsag
    
3.将产生的随机字符串返回给客户端浏览器 让浏览器保存
sessionid :随机字符串
    
# 会话session的key,拿到随机字符串
request.session.session_key
    
#获取session
    request.session.get('k1')
    1.django内部会自动去请求头里获取cookie
    2.拿着session所对应的随机字符串去django_session表中一一对比
    3.如果对比上了,会将随机字符串对应的数据获取出来 自动放入request.session中
      如果没有就是一个空字典
        
#删除session
     request.session.delete()
     客户端和服务端全部删除
     request.session.flush()
     只会根据浏览器的不同删对应的数据
    
#如何设置失效时间
   设置会话session和cookie的超时时间
       request.session.set_expiry(value)
        *如果value是整数 session会在数秒后失效
        *如果value是datatime或timedata,session就会在这些时间后失效
        *如果value是0 用户关闭浏览器session就会失效
        *如果value是none,session会依赖全局session失效策略
def set_session(request):
    request.session['k1']='ldd1'
    request.session.set_expiry(5) #键值有效期5秒
    request.session['k2']='ldd2'
    request.session['k3']='ldd3'  
    #设置多条数据也只会在服务端存一条数据,只针对不同浏览器存不同数据
    return HttpResponse('设置成功')

def get_session(request):
    if request.session.get('k1'):
        res=request.session.get('k1')
        print(res)
        return HttpResponse('获取成功')
    return HttpResponse('失效了')

def del_session(request):
    # request.session.delete() #客户端服务端全部删除
    request.session.flush()
    return HttpResponse('删除了')

django中间件

class SessionMiddleware(MiddlewareMixin):
    def __init__(self, get_response=None):
        self.get_response = get_response
        engine = import_module(settings.SESSION_ENGINE)
        self.SessionStore = engine.SessionStore

    def process_request(self, request):
        session_key = request.COOKIES.get(settings.SESSION_COOKIE_NAME)
        request.session = self.SessionStore(session_key)

    def process_response(self, request, response):
        
class CsrfViewMiddleware(MiddlewareMixin):
    def process_request(self, request):
        csrf_token = self._get_token(request)
        if csrf_token is not None:
            # Use same token next time.
            request.META['CSRF_COOKIE'] = csrf_token

    def process_view(self, request, callback, callback_args, callback_kwargs):
        if getattr(request, 'csrf_processing_done', False):
            return None
    def process_response(self, request, response):
        
class MessageMiddleware(MiddlewareMixin):
    """
    Middleware that handles temporary messages.
    """

    def process_request(self, request):
        request._messages = default_storage(request)

    def process_response(self, request, response):

django默认有7个中间件

  • 只要你想要做一些网站的全局性功能 你都应该考虑使用django的中间件

    • 全局的用户登录校验
    • 全局的用户访问频率校验
    • 全局的用户权限校验()

    django的中间件是所有框架里面做的最完善的

对象 字符串 》》反射
全局 》中间件

  • 并且支持用户自定义中间件 然后暴露给用户五个可以自定义的方法

需要掌握

  • process_request
    • 请求来的时候会按照settings配置文件中从上往下的顺序 依次执行每一个中间件内部定义的process_request方法 如果中间件内部没有该方法 直接跳过执行下一个中间件
    • 该方法一旦返回了HTTPresponse对象,那么请求会立刻停止往后走 原路立即返回
  • process_response
    • 响应走的时候会按照settings配置文件从下往上的顺序 依次执行每一个中间件内部定义的process_response方法
    • 该方法必须有两个形参 并且必须返回response形参 不返回直接报错
    • 该方法返回什么(HTTPresponse对象)前端就能获得什么
  • 当process_request方法直接返回HTTPresponse对象之后 会直接从当前中间件里面的process_response往回走
  • 没有执行的中间件都不会再执行

需要了解

  • process_view(self,request,view_name,*args,**kwargs)
    • 路由匹配成功之后执行视图函数之前触发
    • 如果该方法返回了一个HTTPresponse对象 那么会从下往上依次经过每一个中间件里面的process_response方法
  • process_template_response
    • 当你返回的对象中含有render属性指向的是一个render方法的时候才会触发 从下往上的顺序
def md(request):
    print('我是视图函数md')
    def render():
        return HttpResponse('我很奇怪')
    obj=HttpResponse('我也很体贴')
    obj.render=render
    return obj
  • process_exception
    • 当视图函数中出现错误 会自动触发 顺序是从下往上

上面五个方法,会在特定的阶段自动触发

  • 如果形参中含有response 那么必须要返回

你可能感兴趣的:(12.4 cookies\sessions)