会话技术

出现场景

  • 服务器如何识别客户端(服务器怎么知道你是你)
  • Http在Web开发中基本都是短连接

请求生命周期

  • 从Request开始
  • 到Response结束

种类:cookie,session,token

Cookie

cookie本身由浏览器生成,通过Response将cookie写到浏览器上,下一次访问,浏览器会根据不同的规则携带cookie过来

cookie不能跨浏览器

cookie语法

    response.set_cookie(key,value[,max_age=None,exprise=None)]
    request.GET.get(key,defaultvalue)

response.set_cookie(key,value,max_age=None,exprise=None)生成cookie
response.set_signed_cookie(key,value,salt)生成加密cookie

max_age:  整数,指定cookie过期时间
expries  
:   整数,指定过期时间,还支持是一个datetime或  timedelta,可以指定一个具体日期时间
max_age和expries两个选一个指定

过期时间的几个关键时间
max_age 设置为
0 浏览器关闭失效
设置为None永不过期
expires=timedelta(days=10) 10天后过期

  - 客户端会话技术
     - 数据存储在客户端
  - cookie以键值对存储

cookie特性:

  - 支持过期时间
  - 默认Cookie会自动携带,本网站所有Cookie
  - Cookie不能跨域名,跨网站

服务器怎么操作浏览器

  - 通过HttpResponse
  - **Cookie默认不支持中文,需要转换**
  - 可以加盐
     - 加密
     - 获取的时候需要解密

实践:cookie

url:url('^setcookie/', views.set_cookie, name='set_cookie'),
views:

def set_cookie(request):
    response = HttpResponse('设置cookie')
    response.set_cookie('username', 'Rock')   # 设置了cookie
    return response

结果可以看到:

可以看到响应回cookie
这时我们再访问之前建立的hello

我们可以看到我们在请求时,是访问cookie请求的
接着我们再新建url用来获取cookie,并返回给客户端

url('^getcookie/', views.get_cookie, name='set_cookie'),

views

def get_cookie(request):
    username = request.COOKIES.get('username')
    return HttpResponse(username)


我们可以看到服务器成功获取并返回了我们的cookie

那这些可以有何用呢?我们可以用登录来做一个实验,详细请看下面的实践:cookie登录

实践:cookie登录实验

登陆

  • 首先有一个页面(静态显示)

    • 页面中有输入框
    • 有登陆按钮
  • 点完登陆,默认进入个人中心(静态显示)
  • 个人中心可以显示用户名(逻辑操作)

我们新建一个url:

url('^login/', views.login, name='login'),

新建一个login.html模板

    <title>login</title>
</head>
<body>
<form action="" method="post">
    <span>用户名:</span><input type="text" placeholder="请输入用户名" name="uname">
    <br>
    <button>登录</button>
</form>
</body>
</html>

客户端向服务端传数据,数据有很多,以字典形式接收
5行中的name='uname'是指定k的字段
views:

def login(request):
    return render(request, 'login.html', )

但是我们应该还有一个执行登录的接口,点击登录按钮,将用户名进行保存的操作(目前只存到前端)
新建url

url('^do_login/', views.do_login, name='do_login'),

views:

def dologin(request):
    uname = request.POST.get('uname')
    # 暂时不用登录验证,直接返回登陆成功
    response = HttpResponse('登陆成功')
    # 接着存到cookie
    response.set_cookie('uname',uname)
    return response

接着我们要设计一个个人中心
新建url:

url('^mine/', views.mine, name='mine'),

views:

def mine(request):
    # 获取cookie
    uname = request.COOKIES.get('uname')
    return HttpResponse(uname)

然后补全html中的action路径

 action="{% url 'app:do_login' %}

再将settings.py中的csrf注释掉

下面让我们进行测试:
首先查看mine页面

返回的是none这表名没有cookie返回给我们
我们再登录login:

然后点击登录,返回登录成功,再访问mine

我们可以看到成功返回

大概思路:输入用户名,用户名通过name='uname',通过前端进行存储,存储之后再将uname通过
 uname = request.COOKIES.get('uname') 进行后端的获取,再将用户名返回给mine中。

优化:

  1. 修改views:
def do_login(request):
    uname = request.POST.get('uname')
    # 点击登录之后直接利用重定向跳转到mine页面,省去了手动输入mine页面地址操作
    response = HttpResponseRedirect(reverse('app:mine'))
    # 接着存到cookie
    response.set_cookie('uname', uname)
    return response
  1. 当我们没有点击过登录,直接访问mine返回的是none,这是我们需要自动跳转登陆界面:
def mine(request):
    # 获取cookie
    uname = request.COOKIES.get('uname')
    if uname:
        return HttpResponse(uname)
    # redirect是重定向简写,reverse是views中的反向解析
    return redirect(reverse('app:login'))


cookie一般默认浏览器关闭就消失
我们也可以设置cookie的过期时间

response.set_cookie('uname', uname, max_age=30)# 30秒

对cookie加盐

def do_login(request):
    uname = request.POST.get('uname')
    # 点击登录之后直接利用重定向跳转到mine页面,省去了手动输入mine页面地址操作
    response = HttpResponseRedirect(reverse('app:mine'))
    # 接着存到cookie
    # response.set_cookie('uname', uname, max_age=30)
    response.set_signed_cookie('conrent', uname, 'rock')
    return response

def mine(request):
    # 获取cookie
    uname = request.COOKIES.get('content')
    if uname:
        return HttpResponse(uname)
    # redirect是重定向简写,reverse是views中的反向解析
    return redirect(reverse('app:login'))

登录,输入用户名www

对cookie解密

def mine(request):
    # 获取cookie
    # 解密
    uname = request.get_signed_cookie('content', salt='rock')
    if uname:
        return HttpResponse(uname)
    return redirect(reverse('app:login'))

实践:cookie退出登录

新建mine.html做一个网页用来退出登录

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>mine</title>
</head>
<body>
<h2>欢迎回来:{{ uname }}</h2>
<a href="{% url 'app:logout' %}">退出</a>
</body>
</html>

新建url

 url('^logout/', views.logout, name='logout'),

views:我们将mine函数返回的httpresponse,改为返回html网页

def mine(request):
    # 获取cookie
    # uname = request.COOKIES.get('content')
    uname = request.get_signed_cookie('content', salt='rock')
    if uname:
        return render(request, 'mine.html', context={'uname': uname})
    # redirect是重定向简写,reverse是views中的反向解析
    return redirect(reverse('app:login'))


# 退出就是让cookie消失,删除浏览器中的cookie,通过response让服务器
# 通知浏览器删除cookie
def logout(request):
    response = redirect('app:login')
    response.delete_cookie('content')
    return response

可以观察到,通过设置了过期的cookie来达到删除cookie效果

优化:

当我们不携带cookie时去访问mine时会发现报错,因为获取不到content,这时候我们要提高兼容性
views:

def mine(request):
    # 获取cookie
    # uname = request.COOKIES.get('content')
    try:
         uname = request.get_signed_cookie('content', salt='rock')
         if uname:
             return render(request, 'mine.html', context={'uname': uname})
    except Exception as e:
        print('获取失败')
    return redirect(reverse('app:login'))

问题怎么让cookie支持中文

base64

最后修改:2024 年 03 月 13 日
如果觉得我的文章对你有用,请随意赞赏