zoukankan      html  css  js  c++  java
  • django的Cookie Session

     Cookie

          初识cookie的设置和获取 示例

    from django.shortcuts import render, redirect
    from django.shortcuts import HttpResponse
    from django.views import View
    
    from app02 import models
    from django.utils.safestring import mark_safe
    # Create your views here.
    
    user = {
        'username': 'zmd',
        'password': '123'
    }
    class Login(View):
        def get(self,request):
            return render(request,'app02_cookie_login.html')
    
        def post(self,request):
            u = request.POST.get('username')
            p = request.POST.get('pwd')
            if u != user.get('username'):
                return render(request,'app02_cookie_login.html')
            if p == user.get('password'):
                res = redirect('/database_study/index/')
                res.set_cookie('username',u)
                return  (res)
            else:
                return render(request,'app02_cookie_login.html')
    class Index(View):
        def get(self,request):
            current_user = request.COOKIES.get('username')
            if not current_user:
                return redirect('/database_study/login/')
            else:
                return render(request,'app02_cookie_index.html',  {'current_user':current_user})

    一、设置Cookie

      1、将要返回给客户端的内容自定义变量---使用 render或redirect 或HttpResponse

    response = redirect('/database_study/index/')
    response = render(request,'app02_cookie_index.html')
    response = HttpResponse('xxxxx')

      2、自定义变量.set_cookie('cookie_key','value')

    response.set_cookie('username',u)

       可以设置的内容有

    rep.set_cookie(key,value,...)
    rep.set_signed_cookie(key,value,salt='加密盐',...)
        参数:
            key,              键
            value='',         值
            max_age=None,     超时时间
            expires=None,     超时时间(IE requires expires, so set it if hasn't been already.)
            path='/',         Cookie生效的路径,/ 表示根路径,特殊的:跟路径的cookie可以被任何url的页面访问
            domain=None,      Cookie生效的域名
            secure=False,     https传输
            httponly=False    只能http协议传输,无法被JavaScript获取,即document.cookie(不是绝对,底层抓包可以获取到也可以被覆盖)
      expires超时时间设置:
    import datetime
    current_time = datetime.datetime.now()
    expire_time = current_time + datetime.timedelta(seconds=5)
    print(current_time)
    print(expire_time)
    response.set_cookie('username', u, expires=expire_time)

       httponly=True 测试js获取cookie

    response.set_cookie('username', u, expires=expire_time)
    response.set_cookie('usertype', 'admin', httponly=True)

    js获取没有获取到cookie 中usertype

    document.cookie
    "csrftoken=EsHHdjGDkXypo8L7VEVJq2rrGqn4o5YsWjwIk9ivtDLmaearYlbxnxa7SECRiRCo; username=zmd"

      3、案例:设置每页显示数据数量[xx条/页],设置cookie。后台获取设置值,查询指定范围的数据量

      前端js设置cookie  

    <select id="page_size" onchange="changePageSize(this)">
    <option value="10">10条/页</option>
    <option value="30">30条/页</option>
    <option value="50">50条/页</option>
    </select>

      <script src="/static/jquery-2.2.3.min.js"></script> <script src="/static/jquery.cookie.js"></script> <script> {# 获取每页显示数量设置cookie #} function changePageSize(ths) { let per_page_count = $(ths).val(); $.cookie('per_page_count',per_page_count); console.log(per_page_count) } {# 当页面加载完成后,获取cookie中设置的每页显示数量,选中当前设置的值 #} $(function () { let per_page_count = $.cookie('per_page_count'); $("#page_size").val(per_page_count) }) </script>

      后端获取cookie 

    page_size = int(request.COOKIES.get('per_page_count'))

       

     4、设置/获取加密Cookie   :

      设置:response.set_signed_cookie('signed_username', u, salt='加密用字符串')

      获取:request.get_signed_cookie('signed_username', salt='加密用字符串')

    # 设置加密Cookie
    response.set_signed_cookie('signed_username', u, salt='Wyf@1314')
    
    # 获取加密Cookie
    signed_username = request.get_signed_cookie('signed_username',  salt='Wyf@1314')

     

    基于cookie用户登录身份认证应用示例

    1、FBV 函数方式

         自己手写认证装饰器

    from django.shortcuts import render, redirect
    
    from app02 import models
    from django.utils.safestring import mark_safe
    # Create your views here.
    
    user = {
        'username': 'zmd',
        'password': '123'
    }
    class Login(View):
        def get(self,request):
            ...
        def post(self,request):
            ...
    # 自己手写用户身份认证装饰器,未认证直接跳到登录页面,已认证就执行传进来的函数
    def auth(func):
        def inner(request,*args, **kwargs):
            v = request.get_signed_cookie('signed_username',  salt='Wyf@1314')
            if not v:
                return redirect('/database_study/login/')
            return func(request, *args, **kwargs)
        return inner
    
    from django.utils.decorators import method_decorator
    
    
    @auth
    def index(request):
        if request.method == 'GET':
            signed_username = request.get_signed_cookie('signed_username',  salt='Wyf@1314')
            return render(request, 'app02_cookie_index.html', {'current_user': signed_username})

      2、CBV方式 from django.utils.decorators import method_decorator

       使用方法:@method_decorator(装饰器函数, name='要被装饰的函数名')

      将装饰器装饰到dispatch函数上,对于该类所有http请求方法都加了认证(dispatch函数在所有函数执行前执行)
    from django.utils.decorators import method_decorator
    
    
    @auth
    def index(request):
        if request.method == 'GET':
            signed_username = request.get_signed_cookie('signed_username',  salt='Wyf@1314')
            return render(request, 'app02_cookie_index.html', {'current_user': signed_username})
    
    
    # 装饰器装饰到dispatch函数上,对于该类所有http请求方法都加了认证(dispatch函数在所有函数执行前执行)
    @method_decorator(auth, name='dispatch')
    class Index(View):
        def get(self,request):
            # current_user = request.COOKIES.get('username')
            signed_username = request.get_signed_cookie('signed_username',  salt='Wyf@1314')
            # print('signed_username', signed_username)
            # if not current_user:
            #     return redirect('/database_study/login/')
            # else:
            return render(request,'app02_cookie_index.html',  {'current_user':signed_username})

     

     

     

    Session

      服务器端存储Session  + Cookie中存储 sessionid

      Session 不存在敏感信息。一个Session ID对应一个用户登录信息。用户登录信息只在服务端存储。

      语法:request.session['xxxx'] = xxxx

      解析:session做了如下事儿

        1、生成随机字符串

        2、作为sessionid的值写入Cookie

        3、将sessionid 和对应的 值(自定义的数据内容加密后)保存到django的数据库中

      示例:views.py

    from django.shortcuts import render, redirect
    from django.views import View
    # Create your views here.
    
    
    user = {
        'username': 'zmd',
        'password': '123'
    }
    
    
    class SessionLogin(View):
        def get(self, request):
            return render(request, 'session_login.html')
    
        def post(self, request):
            u = request.POST.get('username')
            p = request.POST.get('pwd')
            if u != user.get('username'):
                return render(request,'session_login.html')
            if p == user.get('password'):
                request.session['current_user'] = u
                return redirect('/session_index/')
            else:
                return render(request, 'session_login.html')
            
    class SessionIndex(View):
        def get(self,request):
            current_user = request.session.get('current_user')
            print(current_user)
            if current_user:
                return render(request, 'session_index.html', {'current_user':current_user })
            else:
                return redirect('/session_login/')

      前端html

      session_login.html
        <form action="/session_login/" method="post">
            <input type="text" name="username">
            <input type="password" name="pwd">
            <input type="submit" value="登录">
        </form>
      session_index.html
    <h2> 欢迎登陆 : {{ current_user }}</h2>
    <h2> 欢迎登陆:
    {{ request.session.current_user }} </h2>

      查看数据库中存储的session示例

     1、session常用方法

    # Django Session 的使用方法
    def index(request):
        # 获取、设置、删除Session中数据
        session_key = request.session.session_key  # ---> 用户session的随机字符串
        request.session['k1'] = 'xxxx'         # ---> 设置Session中数据
        k1 = request.session['k1']             # ---> 获取Session中数据, 不存在会报错
        request.session.get('k1')              # ---> 不存在返回None
        request.session['k1'] = 123            # ---> 设置session中存储的信息
        request.session.setdefault('k1', 123)  # ---> 存在则不设置
        del request.session['k1']              # ---> 删除本次请求sessionid 对应session中对应的指定数据
        request.session.delete("session_key")  # ---> 删除当前用户的所有Session数据
        request.session.clear()                # ---> 注销:删除当前用户的所有Session数据 == request.session.delete(request.session.session_key)
        request.session.clear_expired()        # ---> 将所有Session失效日期小于当前日期的数据删除
        request.session.exists("session_key")  # ---> 检查 用户session的随机字符串 在数据库中是否
        request.session.exists("session_key")  # ---> 检查 用户session的随机字符串 在数据库中是否存在
       request.session.set_expiry(value=0) # ---> 设置过期时间秒
        # *如果value是个整数,session会在些秒数后失效。
        # *如果value是个datatime或timedelta,session就会在这个时间后失效。
        # *如果value是0, 用户关闭浏览器session就会失效。
        # *如果value是None, session会依赖全局session失效策略。
    
        # 所有 键、值、键值对
        request.session.keys()
        request.session.values()
        request.session.items()
        request.session.iterkeys()
        request.session.itervalues()
        request.session.iteritems()

     2、基于session的登录、注销示例

    class SessionLogout(View):
        def get(self,request):
            request.session.clear()
            return redirect('/session_login/')
    class SessionLogin(View):
        def get(self, request):
            return render(request, 'session_login.html')
    
        def post(self, request):
            u = request.POST.get('username')
            p = request.POST.get('pwd')
            if u != user.get('username'):
                return render(request,'session_login.html')
            if p == user.get('password'):
                request.session['current_user'] = u
                return redirect('/session_index/')
            else:
                return render(request, 'session_login.html')
    
    class SessionIndex(View):
        def get(self,request):
            current_user = request.session.get('current_user')
            print(current_user)
            if current_user:
                return render(request, 'session_index.html')
            else:
                return redirect('/session_login/')

        html示例:

        模板渲染中可以直接使用request对象,获取对象中的值 {{ request.session.current_user }}

    session_index.html
    <h2> 欢迎登陆 : {{ request.session.current_user }}</h2>
    <a href="/session_logout/">注销</a>
    session_login.html
    <body>
        <form action="/session_login/" method="post">
            <input type="text" name="username">
            <input type="password" name="pwd">
            <input type="submit" value="登录">
        </form>
    </body>

     3、session 默认配置

        常用设置:

        SESSION_SAVE_EVERY_REQUEST = False # 每次请求都更新Session (更新过期时间) 默认为False,不更新。

        详细一览:

    # Django默认支持Session,并且默认是将Session数据存储在数据库中,即:django_session表中。
    #settings.py
    
    SESSION_ENGINE = 'django.contrib.sessions.backends.db'  # 引擎存到数据库(默认)
    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,默认修改之后才保存(默认)

      3.1缓存session 

      默认在内存中,django内部默认只支持memcached

    # 缓存Session配置
    # settings.py
    
    SESSION_ENGINE = 'django.contrib.sessions.backends.cache'  # 引擎
    SESSION_CACHE_ALIAS = 'default'  # 使用的缓存别名(默认内存缓存,也可以是memcache),此处别名依赖缓存的设置
    
    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,默认修改之后才保存
    
    CACHES = {
        'default': {
            'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
            'LOCATION': [
                '1.1.1.1:11211',
                '2.2.2.2:11211'
            ]
        }
    }

      3.2 文件session 

      需要指定存储session的文件

    # 文件session
    # settings.py
    
    SESSION_ENGINE = 'django.contrib.sessions.backends.file'  # 引擎
    SESSION_FILE_PATH = None  
    # 缓存文件路径,如果为None,则使用tempfile模块获取一个临时地址tempfile.gettempdir() # 如:/var/folders/d3/j9tj0gz93dg06bmwxmhh6_xm0000gn/T

    3.3 缓存 + 数据库session

    SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'        # 引擎

    3.4 加密session

    SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies'   # 引擎
     

      

  • 相关阅读:
    列举 spring 支持的事务管理类型?
    memcached 能够更有效地使用内存吗?
    Redis 集群方案什么情况下会导致整个集群不可用?
    详细描述一下 Elasticsearch 更新和删除文档的过程?
    Redis 常见性能问题和解决方案?
    如果有大量的 key 需要设置同一时间过期,一般需要注意什么?
    synchronized 和 ReentrantLock 的区别?
    Redis 支持的 Java 客户端都有哪些?官方推荐用哪个?
    memcached 最大的优势是什么?
    memcached 是原子的吗?
  • 原文地址:https://www.cnblogs.com/zhangmingda/p/13340551.html
Copyright © 2011-2022 走看看