• Django操作session和cookie


    http协议四大特性


    1. 基于TCP/IP作用于应用层的协议
    2. 基于请求响应
    3. 无状态: 同一个客户端发送多次请求没有任何关联
    4. 无连接

    会话跟踪技术

    多次请求之间记录消息来弥补http无状态保存的缺点(使多次请求有联系)、


    • cookie

    具体一个浏览器针对一个服务器存储其消息的键值对(key=value)

    • 客户端-服务端

    客户端第一次访问服务端的某一个功能,比如login功能,一开始客户端的请求头里是带着空字典去访问的,访问成功后,服务器后生成一个cookie给到客户端,比如说下面的cookie:


    Cookie: BAIDUID=F00480318ED42C27C35D3A2FBE2B0AD7:FG=1; BIDUPSID=F00480318ED42C27C35D3A2FBE2B0AD7; PSTM=1561713680; BD_UPN=123253; BDUSS=npyYVNyVEMwaldpTUxBV1BCUlhBfmVRTGZJclFlaENWQ0tDeGJyVFQ3a09rRnBkSVFBQUFBJCQAAAAAAAAAAAEAAABYUcuESmF2YV93aW5uZXIyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4DM10OAzNdf; BD_HOME=1; H_PS_PSSID=26525_1453_21121_29522_29518_28518_29098_28838_29071
    

    当客户端再次去访问的时候,客户端就带着这个味cookie来访问,服务器就判定了这个客户端访问过该功能,则不再生成cookie,直接让客户端访问其功能


    cookie一旦生成,每次访问都会带着,除非失效,cookie是存在磁盘上的


    访问不同的web服务的cookie是不同的,不同客户端访问同一个web服务的cookie也是不同的

    set_cookie.png


    • session

      保存在服务端上的键值对
      服务端产生随机的串儿返回给客户端,服务端找一个地方将串儿与对应的信息存起来{'随机字符串':'敏感信息'}

    session.png

    客户端第一次骑牛携带的cookie:{}

    服务器设置session: Request.session['username']='yuan' 设置session实现了3步

    1. 生成随机字符串 123ghrjsdg
    2. 把这次给浏览器的响应体里设置set_cookie, key是sessionid,值就是生成的随机字符串 123ghrjsdg
    3. 在django-session表中添加记录, session-key 是生成的随机字符串 123ghrjsdg,session-data是 {'username':'yuan'}

    客户端第二次请求携带的cookie: {sessionid=123ghrjsdg}到某一个视图函数(访问某个功能)

    服务器中的视图函数取session request.session['username'] 实现了3步

    1. 客户端携带着cookie: {sessionid=123ghrjsdg}, 视图函数会先读取到cookie中的随机字符串 123ghrjsdg
    2. 然后视图函数会去django-session表中找到session-key为cookie中的随机字符串 123ghrjsdg的记录
    3. 然后从这条记录中找到{'username':'yuan'},从而取出值,如果视图函数是登入功能的话,就可以判定这个发请求来的客户端登录成功了,而且登录名字是yuan

    没有cookie,session没有任何存在的意义,当我们在浏览器上禁用了cookie,我们就无法登陆京东或者淘宝,因为服务器并没有session,验证无法通过,就无法登入了,session的查看方式在console下的application下的cookies可以查看


    设置cookie


    cookie语法

    响应体: HttpResponse() ,render(), redirect()

    设置cookie必须用响应体设置 obj.set_cookie(key,value)

    设置完cookie,可以在响应头中查看 request.COOKIE.get(key) / request.COOKIE[key]

    cookie超时时间: max_age(ie不支持), expires(ie支持,支持时间对象)

    如果不设置超时时间,cookie就远生效

    有效路径(path): 针对哪些路径下的视图函数能取到设置的cookie


    代码验证

    models.py

    from django.db import models
    
    
    class Userinfo(models.Model):
        user=models.CharField(max_length=32)
        pwd=models.CharField(max_length=32)
    

    数据库测试数据

    test.png


    urls.py

    from django.conf.urls import url
    from django.contrib import admin
    from app01 import views
    
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^login/', views.login),
        url(r'^index/', views.index),
    ]
    

    views.py

    from django.shortcuts import render, HttpResponse, redirect
    
    # Create your views here.
    
    from app01.models import Userinfo
    
    
    def login(request):
        if request.method == 'POST':
            user = request.POST.get('user')
            pwd = request.POST.get('pwd')
            s_user = Userinfo.objects.filter(user=user, pwd=pwd).first()
            print(s_user.user, s_user.pwd)
            if s_user:
                # 登录成功
                response = HttpResponse('登录成功')
                response.set_cookie('name', s_user.user)
                response.set_cookie('pwd', s_user.pwd, path='/index/')
    
                # 设置用户的上次访问时间
                import datetime
                now = datetime.datetime.now().strftime('%Y-%m-%d %X')
                response.set_cookie('now', now)
                return response
            else:
                # 登录失败
                pass
        return render(request, 'login.html')
    
    
    def index(request):
        print('index', request.COOKIES)
        name = request.COOKIES.get('name')
        now = request.COOKIES.get('now', "")
        if name:
            return render(request, 'index.html', locals())
        return redirect('/login/')
    
    
    def test(request):
        print('test', request.COOKIES)
        return HttpResponse('test')
    

    login.html

    <body>
    <form action="" method="post">
        {% csrf_token %}
        用户名 <input type="text" name="user">
        密码 <input type="text" name="pwd">
        <input type="submit" value="submit">
    </form>
    </body>
    

    index.html

    <body>
    <h1>hi {{ name }}</h1>
    </body>
    

    当用户访问http://127.0.0.1:8000/login/,如果验证通过,则登录成功,成功返回设置的cookies,以及可以看到返回的消息


    当浏览器输入网址http://127.0.0.1:8000/index/,可以查看到在login视图函数中设置的cookies


    当浏览器输入网址http://127.0.0.1:8000/test/,不可以查看login函数中设置的pwd这个cookies


    案例


    urls.py

    from django.conf.urls import url
    from django.contrib import admin
    from app01 import views
    
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^reg/', views.reg),
        url(r'^login/', views.login),
        url(r'^index/', views.index),
        url(r'^home/', views.home),
        url(r'^xxx/', views.xxx),
    ]
    

    views.py

    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 == 'lyysb' and password == '123':
                old_path = request.GET.get('next')
                if old_path:
                    obj = redirect(old_path)
                else:
                    obj = redirect('/home/')
                # 用户登录成功 朝浏览器设置一个cookie
                obj.set_cookie('name', 'lyysb')
                
                # 设置上次访问时间
                import datetime
                now = datetime.datetime.now().strftime('%Y-%m-%d %X')
                obj.set_cookie('time', now)
                return obj
        return render(request, 'login.html')
    
    
    from functools import wraps
    
    
    def login_auth(func):
        @wraps(func)
        def inner(request, *args, **kwargs):
            print(request.get_full_path())
            old_path = request.get_full_path()
            # 校验cookie
            if request.COOKIES.get('name'):
                return func(request, *args, **kwargs)
            return redirect('/login/?next=%s' % old_path)
    
        return inner
    
    
    @login_auth
    def index(request):
        # print(request.COOKIES.get('name'))
        # if request.COOKIES.get('name'):
        last_time = request.COOKIES.get('time',"")
        return render(request, 'index.html', {'last_time': last_time})
    
    
    @login_auth
    def home(request):
        return HttpResponse('我是home页面,只有登陆了才能看')
    
    
    @login_auth
    def xxx(request):
        return HttpResponse('我是xxx页面,只有登陆了才能看')
    

    login.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Title</title>
        <script
                src="http://code.jquery.com/jquery-3.4.1.js"
                integrity="sha256-WpOohJOqMqqyKL9FccASB9O0KwACQJpFTUBLTYOVvVU="
                crossorigin="anonymous"></script>
        <!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css"
              integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
    
        <script src="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js"
                integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa"
                crossorigin="anonymous"></script>
    </head>
    <body>
    <form action="" method="post">
        <p>username<input type="text" name="username"></p>
        <p>password<input type="text" name="password"></p>
        <input type="submit">
    </form>
    </body>
    </html>
    
    

    index.html

    <body>
    <h1>index</h1>
    <p>上次访问时间:{{ last_time }}</p>
    </body>`
    
    

    设置Session


    session语法

    1. 设置Sessions值 request.session['session_name']='admin'
    2. 获取Session值 session_name=request.session['session_name']
    3. 删除Session值 del request.session['session_name']
    4. Flush() 删除当前的会话数据并删除会话的Cookie 这用于确保前面的会话数据不可以再次被用户的浏览器访问

    代码验证

    models.py

    from django.db import models
    
    
    class Userinfo(models.Model):
        user=models.CharField(max_length=32)
        pwd=models.CharField(max_length=32)
    
    

    数据库测试数据

    test.png


    urls.py

    from django.conf.urls import url
    from django.contrib import admin
    from app01 import views
    
    urlpatterns = [
        url(r'^login_session/', views.login_session),
        url(r'^index_session/', views.index_session),
    ]
    
    

    views.py

    from django.shortcuts import render, HttpResponse, redirect
    
    # Create your views here.
    
    from app01.models import Userinfo
    
    def login_session(request):
        if request.method == 'POST':
            user = request.POST.get('user')
            pwd = request.POST.get('pwd')
    
            user = Userinfo.objects.filter(user=user, pwd=pwd).first()
    
            if user:
                request.session['is_login'] = True
                request.session['username'] = 'hppsb'
                import datetime
                now = datetime.datetime.now().strftime('%Y-%m-%d %X')
                request.session['now'] = now
                return HttpResponse('登录成功')
            '''
            1. 生成一个随机字符串  	0ps4avkhy95v4hbh1f0bae4266zlsddd
            2. response.set_cookie('sessionid',dfrtghhtyr)
            3. 在django session 表中创建记录
                    session-key                             session-data
                0ps4avkhy95v4hbh1f0bae4266zlsddd          {'is_login':True,'username':'hhpsb'}
            '''
    
        return render(request, 'login.html')
    
    
    def index_session(request):
        is_login = request.session.get('is_login')
        if is_login:
            name = request.session.get('username')
            now=request.session.get('now')
            return render(request, 'index.html', locals())
        return redirect('/login_session/')
    
    

    login.html

    <body>
    <form action="" method="post">
        {% csrf_token %}
        用户名 <input type="text" name="user">
        密码 <input type="text" name="pwd">
        <input type="submit" value="submit">
    </form>
    </body>
    
    

    index.html

    <body>
    <h1>hi {{ name }}</h1>
    </body>
    
    

    浏览访问http://127.0.0.1:8000/login_session/,验证通过后产生cookie

    session.png


    查看django_session表


    浏览器访问http://127.0.0.1:8000/index_session/

    sessionid2.png


    更新session

    更新操作,如果用户访问过页面,则第二次访问会带着sessionid这个cookie字段来访问,数据库表django_session中的session_key字段不变,如果添加新的session数据,数据库表中的session_data会变化


    views.py

    def index_session(request):
        is_login = request.session.get('is_login')
        if is_login:
            name = request.session.get('username')
            now=request.session.get('now')
            request.session['xxx']='xxx'  # 把这条数据加入session,session_data字段立马变化
            return render(request, 'index.html', locals())
        return redirect('/login_session/')
    
    


    基于session的注销功能


    models.py

    from django.db import models
    
    
    class Userinfo(models.Model):
        user=models.CharField(max_length=32)
        pwd=models.CharField(max_length=32)
    
    

    数据库测试数据

    test.png


    urls.py

    from django.conf.urls import url
    from django.contrib import admin
    from app01 import views
    
    urlpatterns = [
        url(r'^login_session/', views.login_session),
        url(r'^index_session/', views.index_session),
        url(r'^logout/', views.logout),
    ]
    
    

    views.py

    def login_session(request):
        if request.method == 'POST':
            user = request.POST.get('user')
            pwd = request.POST.get('pwd')
    
            user = Userinfo.objects.filter(user=user, pwd=pwd).first()
    
            if user:
                request.session['is_login'] = True
                request.session['username'] = 'hppsb'
                import datetime
                now = datetime.datetime.now().strftime('%Y-%m-%d %X')
                request.session['now'] = now
                return redirect('/index_session/')
            '''
            1. 生成一个随机字符串  	0ps4avkhy95v4hbh1f0bae4266zlsddd
            2. response.set_cookie('sessionid',dfrtghhtyr)
            3. 在django session 表中创建记录
                    session-key                             session-data
                0ps4avkhy95v4hbh1f0bae4266zlsddd          {'is_login':True,'username':'hhpsb'}
            '''
    
        return render(request, 'login.html')
    
    
    def index_session(request):
        is_login = request.session.get('is_login')
        if is_login:
            name = request.session.get('username')
            now=request.session.get('now')
            return render(request, 'index.html', locals())
        return redirect('/login_session/')
    
    def logout(request):
        request.session.flush()
        '''
        做的三步操作:
        1. randon_str=request.COOKIE.get('sessionid')
        2. django-session.objects.filter(session-key=randon_str).delete()
        3. response.delete_cookie("sessionid",randon_str)
        '''
        return redirect('/login_session/')
    

    login.html

    <body>
    <form action="" method="post">
        {% csrf_token %}
        用户名 <input type="text" name="user">
        密码 <input type="text" name="pwd">
        <input type="submit" value="submit">
    </form>
    </body>
    
    

    index.html

    <body>
    <h1>hi {{ name }}</h1>
    </body>
    
    

    浏览器访问http://127.0.0.1:8000/index_session/ 按注销跳转到登录页面


    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失效日期(默认)
    SESSION_EXPIRE_AT_BROWSER_CLOSE = False  # 是否关闭浏览器使得Session过期(默认)
    SESSION_SAVE_EVERY_REQUEST = False  # 是否每次请求都保存Session, 默认修改后才保存(默认)
    
  • 相关阅读:
    七. 多线程编程3.主线程
    七. 多线程编程1.线程的概念
    六. 异常处理12.断言
    liunx 安装 mysql 5.6
    idea Unable to open debugger port (127.0.0.1:58006) Address already in use: JVM_Bind 的解决办法
    liunx 安装redis 4.0
    liunx 安装jdk1.8
    idea 去除xml文件sql语句背景色
    改变数据库和表编码
    mybatis 按in 函数参数顺序排序
  • 原文地址:https://www.cnblogs.com/cjwnb/p/11802829.html
Copyright © 2020-2023  润新知