会话跟踪技术cookie与session——重要概念、基本用法及两个实例

基本概念

会话跟踪技术(cookie与session):在多次请求之间记录相关的信息,来弥补Http协议的“无状态保存”

Http协议的无状态保存:浏览器在访问服务器的时候,多次请求间相互独立,无法记录前一次请求的状态。

cookie将键值信息存到客户端;session将键值信息存到了服务器端。

cookie的基本操作

详见这篇博客:https://www.cnblogs.com/paulwhw/articles/10958473.html

# 注意里面的键值用逗号隔开
1、设置(response) response.set_cookie('key','value')
2、读取(request) request.COOKIES.get('key')
'''
(删除的话建议在本地浏览器删除)
'''

session的基本操作

常用的操作

1、设置session:request.session['key'] = 'value'
             request.session.setdefault('k1',123) # 存在则不设置
2、读取session:request.session['key'] 

#这种方式最常用,既可以清除本地cookie对应的值也可以清除server端数据库中的对应记录 
3、清除session:request.session.flush()

设置session时发生的三件事

1、生成一个随机字符串:session_id:xxxxx

2、加密用户的信息(比如is_login登陆状态或者用户名信息等),将这些信息加密~然后保存到数据库里面django_session表。

django_session表中有三个字段:

session_key保存着随机字符串session_id的值;session_data中保存着第2步中加密后的用户信息数据;expire_date保存着这个session到期的时间(到了这个时间点自动失效,默认为2周)。

3、最后将这个session_id保存到本地的cookie中。

读取session时发生的两件事 

1、从cookie中找到sessionid的值xxxx(就是设置的3步存到本地的随机字符串的值)

2、通过这个随机字符串去server端的django_session表找到对应的那条记录,然后将session_data拿出来进行解密,得到用户设置的数据,进行逻辑判断处理。

cookie的例子 

路由

from django.contrib import admin
from django.urls import path,re_path
from app01 import views

urlpatterns = [
    path('admin/', admin.site.urls),
    re_path('^cookie/$',views.cookie),
    re_path('^index/$',views.index),
    re_path('^test/$',views.test),
]
路由

models文件

from django.db import models

class UserInfo(models.Model):
    name = models.CharField(max_length=32)
    pwd = models.CharField(max_length=32)
models.py

视图函数

from django.shortcuts import render,HttpResponse,redirect
from app01.models import UserInfo

def cookie(request):
    if request.method == 'POST':
        name = request.POST.get('user')
        pwd = request.POST.get('pwd')
        ret = UserInfo.objects.filter(name=name,pwd=pwd).first()
        if ret:
            #登陆成功
            '''
            一、响应体:
            return HttpResponse()
            return render()
            return redirect()
            二、三个问题:
            (1)一次访问成功了后面访问都带着这个cookie——前提是设置了获取cookie
            (2)换一个浏览器访问就变成“新的了”
            (3)同一个浏览器访问不同的服务器携带的cookie不同、独立的。
            '''
            ##设置cookie
            response = HttpResponse('OK')
            ##超时参数 max_age (单位是秒),表示多长时间以后失效
            ##有效路径,表示只给某些路由下的视图函数使用——下面的例子表示只能有路径index下的视图函数访问
            response.set_cookie('is_login',True,max_age=155,path='/index/')
            #保存当前登陆的用户信息
            ##超时参数 expires(IE浏览器不支持max_age,支持这个),表示在固定的时刻失效
            import datetime
            date = datetime.datetime(year=2019,month=8,day=11,hour=12,minute=36,second=55)
            response.set_cookie('username',ret.name,expires=date)
            return response

    return render(request, 'cookie.html')


#如果cookie的页面登陆成功,那么此次访问index的话会携带cookie
def index(request):
    print('index',request.COOKIES) #index {'is_login': 'True', 'csrftoken': 'DyEpXOzbKhtg5Nr8cf3mFm6JF2PuYHcdbWCzfB5eYqjfF9fn2RuGafjge7YVtuNC', 'username': 'whw'}
    ##获取cookie的值
    is_login = request.COOKIES.get('is_login')
    username = request.COOKIES.get('username')

    ##获取上次访问时间
    import datetime
    now = datetime.datetime.now().strftime('%Y-%m-%d  %X ')
    last_time = request.COOKIES.get('last_visit_time')

    ##表示有cookie了
    if is_login:
        response = render(request, 'index.html',{'username':username,'last_time':last_time})
        response.set_cookie('last_visit_time',now)
        return response
    #否则跳转回登陆页面
    else:
        return redirect('/cookie/')


def test(request):
    print('test:',request.COOKIES)#只有中间件的cookie test: {'csrftoken': 'DyEpXOzbKhtg5Nr8cf3mFm6JF2PuYHcdbWCzfB5eYqjfF9fn2RuGafjge7YVtuNC', 'is_login': 'True', 'username': 'whw'}
    return HttpResponse('OK')

cookie.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Cookie</title>
</head>
<body>
<form action="" method="post">
    {% csrf_token %}
    用户名: <input type="text" name="user">
    密 码: <input type="text" name="pwd">
    <input type="submit" value="提交">
</form>
</body>
</html>
cookie.html

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Index</title>
</head>
<body>
<p>Welcome! {{ username }}</p>
<p>上次登陆时间:{{ last_time }}</p>
</body>
</html>
index.html

session的例子

路由

from django.contrib import admin
from django.urls import path,re_path
from app01 import views

urlpatterns = [
    path('admin/', admin.site.urls),
    re_path('^session/$',views.session),
    re_path('^index/$',views.index),
    re_path('^logout/$',views.logout),
]
路由

models文件

from django.db import models

class User(models.Model):
    name = models.CharField(max_length=32)
    pwd = models.CharField(max_length=32)
models.py

视图函数

from django.shortcuts import render,HttpResponse,redirect
from app01.models import User

def session(request):
    if request.method == 'POST':
        name = request.POST.get('user')
        pwd = request.POST.get('pwd')
        ret = User.objects.filter(name=name,pwd=pwd).first()
        if ret:
            request.session['is_login'] = True
            request.session['username'] = ret.name
            ##记录上次“登陆的时间”
            ###注意这个时间写在登陆的逻辑里代表登陆时间,写在index的逻辑里代表访问时间
            import datetime
            now = datetime.datetime.now().strftime('%Y-%m-%d %X')
            request.session['last_visit_time'] = now
            '''
            session的存储会执行三部分内容:
            (1)生成随机字符串(比如是'asd') 
            (2)响应体response:response.set_cookie('sessionid','asd')
            (3)在django-session表中创建一条记录(只看关键的两个):
                session-key(保存随机字符串)  session-data(以字典新式存的上面的session设置的值:{'is_login':True,'username':(ret.name的值)})    
            '''
            return HttpResponse('OK!')

    return render(request,'session.html')

###
def index(request):
    '''
    1.获取随机字符串  request.COOKIE.get('sessionid') 
    2.在django-session表中过滤记录:
        session-key                session-data   
            XXX                         XXX
        obj = django-session.objects.filter(session-key='随机字符串')
    3.从obj中取出session-data,找到对应的键值,注意需要反序列化:obj.session-data.get('is_login')
    '''
    ##保存登陆状态信息
    is_login = request.session.get('is_login')
    username = request.session.get('username')
    last_visit_time = request.session.get('last_visit_time')
    #登陆成功
    if is_login:
        return render(request,'index.html',locals())
    #登陆不成功跳转到登录页面
    else:
        return redirect('/session/')

###
def logout(request):
    # 注销——删掉代表登陆成功信息的session
    #删除所有的信息
    # del request.session['is_login']  这句话只能删除部分
    #用下面这个
    ##删除当前会话数据并删除会话的cookie
    ##这用于确保前面的会话数据不可以再次被用户的浏览器访问
    request.session.flush()
    #注销后跳转到登陆的session主页面
    return redirect('/session/')

session.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Session</title>
</head>
<body>
<form action="" method="post">
    {% csrf_token %}
    用户名: <input type="text" name="user">
    密 码: <input type="password" name="pwd">
    <input type="submit" value="确认">
</form>
</body>
</html>
session.html

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Index</title>
</head>
<body>

<p>Hello! {{ username }}</p>
<p>上次“登陆”时间:{{ last_visit_time }}</p>
<p><a href="/logout/">注销</a></p>
</body>
</html>
index.html

 

posted on 2019-05-31 21:01  江湖乄夜雨  阅读(499)  评论(0编辑  收藏  举报