Django2:Web项目开发入门笔记(25)

2024年04月15日 django Python51

这一篇教程,我们一起来了解Cookie与Session。

Cookie是由Web服务器保存在用户浏览器上的小文本文件,它可以包含有关用户的信息。

当Web服务器创建了Cookies 后,只要在其有效期内(有效期可以由开发人员设定),当用户访问同一个Web服务器时,浏览器首先要检查本地的Cookies,并将其原样发送给 Web 服务器。

这种状态信息称作“Persistent Client State HTTP Cookie”,简称为 Cookies。

以上是引用百度百科中对“Cookie”的描述。

对于“Cookie”的使用,每个人都应该体验过。

例如,我们成功登录百度网站,如果不主动退出,即便是隔一天再打开浏览器进入百度网站,依然能够保持登录状态。

这就是“Cookie”在起作用,它通过将一些信息保存在客户端,解决HTTP的会话保持问题。

提示:HTTP是无状态的,所以无法保持会话状态。保持会话状态是指将同一用户多次进行HTTP连接所发出的不同请求形成关联。

在我们登录百度网站时,服务器创建了“Cookie”文件发送给浏览器进行保存。

当我们再次打开浏览器访问百度网站时,浏览器会先从本地保存的“Cookie”文件中查找与百度网站相匹配的“Cookie”文件,如果存在并有效则回送给服务器,服务器进行相应的验证之后,根据验证结果返回相应的状态到浏览器。

接下来,我们就使用“Cookie”完成一个保持登录状态功能。

1、创建一个简单的模板,添加一个表单。

表单中包含两个状态下的元素。

已登录状态包含一句问候语和一个退出链接。

未登录状态包含一个文本输入框和一个按钮。

示例代码:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
</head>
<body>
<form action="/" method="post">
    {% csrf_token %}
    {% if username %}
        您好,{{ username }}!
        <a href="exit/">退出</a>
    {% else %}
        <input type="text" name="username">
        <input type="submit" value="登录">
    {% endif %}
</form>
</body>
</html>

通过这个模板,我们能够看出,页面呈现什么样的状态,取决于{{ username }}这个变量中是否存在数据内容。

2、添加URL分发配置

示例代码:

path('', siteviews.index),
path('exit/',siteviews.exit),

3、定义视图函数

在视图函数中,我们要对“Cookie”进行设置与读取的操作。

设置“Cookie”比较常用的参数包括:

  • key:键
  • value:值
  • max_age:多少秒后过期
  • expires:什么时间过期
  • path:指定哪些URL可以访问当前“Cookie”文件(默认为“/”,表示所有)
  • domain:指定哪些域名可以访问当前“Cookie”文件(默认为“None”,表示当前域名)
  • secure:默认值为“False”(通过HTTPS传输时需设置为“True”)
  • httponly:默认值为“False”(如果设置为“True”,则只能通过HTTP传输,JS无法获取和修改)

示例代码:

from django.shortcuts import render, HttpResponseRedirect

def index(request):
    if request.COOKIES.get('username', None):  # 读取Cookie信息
        return render(request, 'index.html', {'username': request.COOKIES['username']})  # 读取Cookie信息
    if request.method == 'POST':
        username=request.POST['username']
        res =render(request,'index.html',{'username':username})
        res.set_cookie('username',username,30)  # 设置Cookie信息
        return res
    else:
        return render(request,'index.html')


def exit(request):
    res = HttpResponseRedirect('/')
    res.delete_cookie('username')  # 删除Cookie信息
    return res

完成上述代码后,大家运行开发服务器,在打开的页面中输入一个用户名,点击登录按钮,就能够切换为登录后的状态。

并且,在30秒内刷新当前页面,会持续保持登录状态。

而超过30秒之后,又会恢复未登录状态。

大家可以通过浏览器的开发者工具(F12),查看“Cookie”文件的内容。

在上图中,暴露了一个严重的问题,就是“Cookie”的内容是直接可见的。

所以,切记不要在“Cookie”中存储重要或者敏感的用户信息。

这样直接暴露的“Cookie”信息,非常容易被攻击者盗取并篡改。

但是,我们又需要通过“Cookie”持续保持会话状态。

有一种解决方法是“加盐”和“解盐”,也就是对“Cookie”信息设置时进行加密,读取时进行解密,以防止攻击者使用篡改过的信息欺骗服务器。

我们对之前的视图函数进行修改。

示例代码:

def index(request):
    if request.COOKIES.get('username', None):
        # return render(request, 'index.html', {'username': request.COOKIES['username']})
        <strong>return render(request, 'index.html', {'username': request.get_signed_cookie('username', salt='用于加密的字符串')})</strong>
    if request.method == 'POST':
        username = request.POST['username']
        res = render(request, 'index.html', {'username': username})
        # res.set_cookie('username',username,30)
<strong>        res.set_signed_cookie('username', username, salt='用于加密的字符串')</strong>
        return res
    else:
        return render(request, 'index.html')

上方代码中,注释的内容为修改前的语句,红色内容为修改后的语句。

当这样修改之后,在浏览器中查看到的“Cookie”文件信息,就包含了一段安全密钥。

当我们访问网站时,浏览器会将包含了密钥的“Cookie”信息回送到服务器,服务器对密钥进行解密验证。

这种解决方法虽然提高了安全性,但是用户的信息仍然是暴露的。

目前,最好的解决方式是通过“Cookie”结合“Session”来保持会话状态。

在“Cookie”文件中,只保存一个名为“sessionid”的随机字符串。

而与“sessionid”对应的用户信息全部保存在服务器端。

Django中提供了5种类型的“Session”:

  • 数据库(默认)
  • 缓存
  • 文件
  • 缓存+数据库
  • 加密cookie

这里只为大家介绍默认的基于数据库的“Session”。

使用这种类型的“Session”,需要先完成数据库的设置,并通过“makemigrations”和“migrate”命令完成相关数据表的创建,

然后,就能够在项目中使用“Session”了。

示例代码:

def index(request):
    if request.session.get('username', None):
        return render(request, 'index.html', {'username': request.session['username']})
    if request.method == 'POST':
        username = request.POST['username']
        request.session['username'] = username
        return render(request, 'index.html', {'username': username})
    else:
        return render(request, 'index.html')


def exit(request):
    del request.session['username']
    return HttpResponseRedirect('/')

通过上方代码,我们就完成和之前代码同样的功能。

此时,在浏览器中关于“Cookie”的信息,就不再有用户的信息,只有“sessionid”。

在上图中,大家能够看到,默认“Session”的有效时间为14天,如果需要修改,我们可以在“settings.py”中进行修改。

示例代码:

SESSION_ENGINE = 'django.contrib.sessions.backends.db'  # Session的引擎(默认)
SESSION_COOKIE_NAME = 'mysession'  # Session的Cookie的Key
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 = 604800  # Session的Cookie的有效时长(秒)(默认1209600)
SESSION_EXPIRE_AT_BROWSER_CLOSE = False  # 是否关闭浏览器使得Session过期(默认)
SESSION_SAVE_EVERY_REQUEST = False  # 是否每次请求都保存Session(默认)

修改之后,在浏览器中能够看到信息的变化。

本文链接:http://so.lmcjl.com/news/2185/

展开阅读全文
相关内容