zoukankan      html  css  js  c++  java
  • DAY84-Django框架(十四) cookie and session

    一、cookie

    1.cookie

    ​ cookie 是一个非常具体的东西,指的就是浏览器里面能永久存储的一种数据,仅仅是浏览器实现的一种数据存储功能。

    2.原理

    ​ cookie由服务器生成,发送给浏览器,浏览器把cookie以key:value形式保存到浏览器客户端上,下一次请求同一网站时会把该cookie发送给服务器。由于cookie是存在客户端上的,所以浏览器加入了一些限制确保cookie不会被恶意使用,同时不会占据太多磁盘空间,所以每个域的cookie数量是有限的。

    3.基本使用

    #设置cookie,模拟服务器往浏览器发送cookie
    def set_cookie(request):
        obj = HttpResponse('set_cookie')
        obj.set_cookie('name','xcq')
        obj.set_cookie('name','lqz')#对同一个key的cookie设置value,会覆盖
        return obj
    
    #由于之前的默认设置,是在同一域名中,所以request可以拿到本地域名中的所有cookie
    def get_cookie(request):
        print(request.COOKIES)#以字典形式接受
        print(request.COOKIES['name'])
        obj = HttpResponse('get_cookie')
        return obj
    

    4.参数

    #设置cookie
    set_cookie(
        key, 			#键
        value='', 		#值
        max_age=None, 	#超时时间,以秒为单位,默认None,表示这个cookie会持续到浏览器关闭为止
        expires=None, 	#超时时间,与max_age一样,传一个datatime对象
        path='/',		#Cookie生效的路径,默认为‘/’,表示根路径可以被任何URL的页面访问
        domain=None, 	#Cookie生效的域名,默认为None,表示cookie只能由设置它的站点读取
        secure=False, 	#默认是false,设置成True浏览器将通过HTTPS来回传cookie
        httponly=False  #默认是false,设置成True就无法被JavaScript获取
    ):
    
    
    

    5.加盐cookie

    加盐是为了提高cookie的安全性,因为cookie是明文传递的

    def set_cookie(request):
        obj = HttpResponse('set_cookie')
        obj.set_signed_cookie('name','xcq',salt='123')
        #密钥为123
        #加盐之后,会在xcq之后生成一串随机字符
        return obj
    
    
    def get_cookie(request):
        # print(request.get_signed_cookie('name'))#不写密钥会报错
        print(request.get_signed_cookie('name',salt='123'))
        #想要获得原先的cookie值,要加上密钥
        obj = HttpResponse('get_cookie')
        return obj
    

    6.删除cookie

    def del_cookie(request):
        obj = HttpResponse('del_cookie')
        obj.delete_cookie('name')#只能删除指定key的cookie,无法全部删除
        return obj
    

    7.在浏览器中查看

    ​ 浏览器中按F12,点network---cookies就能看到

    8.简单实例

    要求:

    ​ 1.做一个简单的登录

    ​ 2.做一个装饰器:点击别的页面,强制进入登录页面,登陆成功后跳转回之前的页面

    def login_auth(func):
        def inner(request, *args, **kwargs):
            #拿到被装饰的页面路径
            url = request.get_full_path()
            if request.COOKIES.get('is_login'):
                res = func(request, *args, **kwargs)
                return res
            else:
                #把被装饰的页面路径通过get传递给登陆页面
                return redirect('/login/?next=%s' % url)
    
        return inner
    
    
    def login(request):
        if request.method == 'GET':
            return render(request, 'login.html')
        if request.method == 'POST':
            name = request.POST.get('name')
            pwd = request.POST.get('pwd')
            if name == 'xcq' and pwd == '123':
                #登陆页面通过GET拿到之前的路径
                url = request.GET.get('next')
                if url:
                    #登陆成功且是跳转的登陆,就跳转到之前的页面
                    obj = redirect(url)
                else:
                    obj=HttpResponse('主页')
                obj.set_cookie('is_login', 'True')
                obj.set_cookie('username', name)
                return obj
            return render(request, 'login.html')
    
    
    @login_auth
    def shopping(request):
        return HttpResponse('购物界面')
    
    
    @login_auth
    def order(request):
        return HttpResponse('订单界面')
    

    二、session

    1.session

    ​ session 从字面上讲,就是会话。这是为了解决cookie不安全而出现的

    2.原理

    ​ 服务器为了知道当前发请求给自己的是谁,服务器就要给每个客户端分配不同的“身份标识”,然后客户端每次向服务器发请求的时候,都带上这个“身份标识”,服务器就知道这个请求来自于谁了。至于客户端怎么保存这个“身份标识”,可以有很多种方式,对于浏览器客户端,大家都默认采用 cookie 的方式。

    ​ 服务器使用session把用户的信息临时保存在了服务器上,用户离开网站后session会被销毁。这种用户信息存储方式相对cookie来说更安全,可是session有一个缺陷:如果web服务器做了负载均衡,那么下一个操作请求到了另一台服务器的时候session会丢失。

    3.基本使用

    #设置session
    
    def set_session(request):
        request.session['name']='xcq'
        # request.session['name']='lqz' #对同一个key设置value,会覆盖
        request.session['age']=18
        # request.session.setdefault('age',18)#如果已存在age字段,则不设置
        #设置session,其内部发生了三件事
        #   1.根据其浏览器客户端,生成了唯一的随机字符串sessionid
        
        #   2.去Django的内部数据库django_session存储
        #           session_key(随机字符串)       值(字典形式)                超时时间()
        #               sessionid            {'name':'xcq','age':18}       默认当前时间过两周
        
        #   3.设置了一个cookie:set_cookie('sessionid',随机字符串),浏览器只有通过sessionid来服务器找到对应的数据
    
        request.session.set_expiry(0)
        #如果value是个整数,session会在些秒数后失效。
        #如果value是个datatime或timedelta,session就会在这个时间后失效。
        #如果value是0, 用户关闭浏览器session就会失效。
        #如果value是None, session会依赖全局session失效策略。
    
        return HttpResponse('set_session')
    
    
    
    #获取session
    
    def get_session(request):
        # 获得session数据时:
        #	1.在cookie中获得sessionid对应的随机字符串
        #	2.去django_session中根据唯一sessionid获取对应数据
        
        # 拿到key对应的value,没有则报错
        print(request.session['name'])
    
        # 拿到value,没有不会报错
        print(request.session.get('age'))
    
        # 拿到所有的key
        print(request.session.keys())
    
        # 拿到所有的value
        print(request.session.values())
    
        # 拿到字典形式
        print(request.session.items())
    
        # 拿到sessionid
        print(request.session.session_key)
        return HttpResponse('get_session')
    
    
    
    #删除session
    
    def del_session(request):
        #删除对应的数据
        del request.session['name']
        #删除数据库的session
        request.session.delete()
        #删除数据库和cookie的session
        request.session.flush()
        # 将所有Session失效日期小于当前日期的数据删除
        request.session.clear_expired()
        print(request.session.items())
        return HttpResponse('del_session')
    

    4.setting中的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'   # 引擎
    
    其他公用设置项:
    SESSION_COOKIE_NAME = "sessionid"                       # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串(默认)
    SESSION_COOKIE_PATH = "/"                               # Session的cookie保存的路径(默认)
    SESSION_COOKIE_DOMAIN = None                             # Session的cookie保存的域名(默认)
    SESSION_COOKIE_SECURE = False                            # 是否Https传输cookie(默认)
    SESSION_COOKIE_HTTPONLY = True                           # 是否Session的cookie只支持http传输(默认)
    SESSION_COOKIE_AGE = 1209600                             # Session的cookie失效日期(2周)(默认)
    SESSION_EXPIRE_AT_BROWSER_CLOSE = False                  # 是否关闭浏览器使得Session过期(默认)
    SESSION_SAVE_EVERY_REQUEST = False                       # 是否每次请求都保存Session,默认修改之后才保存(默认)
    

    5.基于session写一个CBV的登陆装饰器

    #重写父类的装饰器
    class Login_user(View):
        #dispatch会对类里的所有方法有效
        def dispatch(self, request, *args, **kwargs):
            url = request.get_full_path()
            if request.session.get('is_login'):
                res = super().dispatch(request, *args, **kwargs)
                return res
            else:
                return redirect('/login/?next=%s' % url)
    
    
    class Login(View):
        def get(self, request):
            return render(request, 'login.html')
    
        def post(self, request):
            name = request.POST.get('name')
            pwd = request.POST.get('pwd')
            if name == 'xcq' and pwd == '123':
                url = request.GET.get('next')
                if url:
                    obj = redirect(url)
                else:
                    obj = HttpResponse('主页')
                request.session['is_login'] = True
                return obj
            return render(request, 'login.html')
    
    
    class Shopping(Login_user):
        def get(self, request):
            return HttpResponse('购物界面')
    
    
    class Order(Login_user):
        def get(self, request):
            return HttpResponse('订单界面')
    
    

    方法二

    from django.utils.decorators import method_decorator
    def login_auth(func):
        def inner(request, *args, **kwargs):
            url = request.get_full_path()
            if request.COOKIES.get('is_login'):
                res = func(request, *args, **kwargs)
                return res
            else:
                return redirect('/login/?next=%s' % url)
    
        return inner
    
    
    class Login(View):
        def get(self, request):
            return render(request, 'login.html')
    
        def post(self, request):
            name = request.POST.get('name')
            pwd = request.POST.get('pwd')
            if name == 'xcq' and pwd == '123':
                url = request.GET.get('next')
                if url:
                    obj = redirect(url)
                else:
                    obj = HttpResponse('主页')
                request.session['is_login'] = True
                return obj
            return render(request, 'login.html')
    
    #@method_decorator(指定装饰器,name=制定方法),如果没有写name=,那也会对所有方法有效
    @method_decorator(login_auth,name='get')
    class Shopping(View):
        def get(self, request):
            return HttpResponse('购物界面')
    
    @method_decorator(login_auth,name='get')
    class Order(View):
        #也可以写在方法上,只会装饰这个方法
        @method_decorator(login_auth)
        def get(self, request):
            return HttpResponse('订单界面')
    
    

    三、cookie与session的区别

    cookie 和session 的区别:

    1. cookie数据存放在客户的浏览器上,session数据放在服务器上。
    2. cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗,考虑到安全应当使用session。
    3. session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能考虑到减轻服务器性能方面,应当使用COOKIE。
    4. 单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。

    打个比方,浏览器客户端是我本人,而服务器就是银行。

    ​ 那么cookie就像是我手里存折,存折上面会记录你每一次的存取钱的记录,而cookie就是记录在浏览器上,我不用去问银行,就知道所有的记录;

    ​ 但session就像是银行卡,我本人手里只有银行卡和唯一的识别卡号,而所有关于我的数据记录都在银行里面,我只能通过卡号去银行(服务器)查询我的卡号所对应的所有的操作记录。

  • 相关阅读:
    JPEG/PNG/GIF图片格式简析
    js-JavaScript常见的创建对象的几种方式
    js-ES6学习笔记-let命令
    js-权威指南学习笔记21
    js-jQuery性能优化(二)
    【读书笔记】iOS-Apple的移动设备硬件
    【读书笔记】iOS-属性中的内存管理参数
    【读书笔记】iOS-自动释放池
    【读书笔记】iOS-分类与协议
    【读书笔记】iOS-动态类型和动态绑定
  • 原文地址:https://www.cnblogs.com/xvchengqi/p/10003248.html
Copyright © 2011-2022 走看看