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是

客户端第二次请求携带的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, 默认修改后才保存(默认)
posted @ 2019-11-06 01:28  cjw1219  阅读(373)  评论(0编辑  收藏  举报