🏘️🏘️个人简介:以山河作礼。
🎖️🎖️:Python领域新星创作者,CSDN实力新星认证,阿里云社区专家博主,CSDN内容合伙人
🎁🎁:Web全栈开发专栏:《Web全栈开发》免费专栏,欢迎阅读!
🎁🎁:文章末尾扫描二维码可以加入粉丝交流群,不定期免费送书。
Cookie和Session
📑📑在 django 中可以通过 html Form 表单实现登录注册功能,但是在这之前,我们有必要简单介绍一下 Cookie 和 Session。比如在某些场景下,在排除用户手动删除浏览器 Cookie 以及 Cookie 未过期的情况下,用户如果在某网站登录过一次,下次访问这个网站,用户不需要输入用户名和密码就可以进入网站,这就是通过 Cookie 和 Session 实现的。
Cookie简述
- Cookie是基于浏览器的一种存储机制,它是在客户端存储数据的一种方式。当用户访问网站时,服务器会将Cookie发送到用户的浏览器,并在用户下次访问时读取Cookie,以便识别该用户。Cookie可以存储较小的数据量,一般用于存储用户的个性化设置和登录状态等信息
- 在学习 HTTP 超文本传输协议的时候,就已经知道 HTTP
是一种无状态的传输协议,对于事务处理没有记忆能力。对于客户端浏览器发出的请求,Web 服务器无法区分是不是源自于同一个浏览器。所以,这时就需要额外的数据用于维持会话。 - 我们通常用来它来记录浏览器端的信息和当前连接的确认信息。Cookie 保存在客户端浏览器存储空间中并以键值对的形式进行存储,也就是说Cookie 也是一个类字典对象。
在 Django 服务器端来设置浏览器的 Cookie 必须通过 HttpResponse 对象来完成,那么如何通过 HttpResponse 实现 Cookie 添加、修改或者删除呢?
📌这里提供了一些方法,如下所示:
HttpResponse.set_cookie(key="", value='', max_age=None, expires=None) #设置或者添加 Cookie
上面的参数分别表示:key、value分别表示 COOKIES 的键与值;max_age 代表 COOKIES的存活时间,以秒为单位;expires 表示具体过期时间,当不指定 max_age 和expires 时,关闭浏览器时此数据失效。
📌那么又如何删除一个 COOKIE 呢?方法如下所示:
HttpResponse.delete_cookie(key) # 输出cookie中的一个
📌实例演示,代码如下所示:
from django.http import HttpResponse
# 设置cookie
def set_cookie_view(request):
resp = HttpResponse() # 创建响应对象
resp.set_cookie('username', 'admin', 10000) # 设置cookie
return resp
# 获取cookie
def get_cookie_view(request):
value = request.COOKIES.get('username')
return HttpResponse('MY COOKIE is: %s' % value)
📌然后配置相应的路由,如下所示:
urlpatterns=[
path('set_cookie/',views.set_cookie_view),
path('get_cookie/',views.get_cookie_view),]
最后访问相应的路由,地址栏输入 1270.0.0.1:8000/index/set_cookie,使用谷歌调试工具,点击 ***work找到响应头,Cookie 都是需要进行加密处理的,在这里为了方便给大家演示,没有进行加密操作。
📌访问 1270.0.0.1:8000/index/get_cookie,可以得到 Cookie 的值,大家也可以自己尝试一下,结果如下图所示:
从上述过程中,我们知道了如何在 Django 中添加 Cookie 或者对其进行取值,但是你可能会发现这个过程其实是不安全的,很容易造成 Cookie 的泄露或者被截取的风险,而且不同浏览器的版本对存储 Cookie 的数量也有限制,且 Cookie自身也有长度限制最大不可超过 4kb,否则会被自动截断。
Session使用
📑📑我们对 Cookie 进行了介绍,并知道在绝大多数实际场景中 Cookie 和 Session 是一起使用的,那么 Session 又是怎么回事呢?在本节我们将对 Session 进行介绍。了解完 Cookie 和 Session 后,我们就可以使用 HTML Form 表单实现一套完整的注册、登录逻辑代码了。
Session的定义
Session 又名会话控制
,它的根本作用是在服务器上开辟一段空间用于保留浏览器和服务器交互时的会话信息。它代表服务器与浏览器的一次会话过程,这个过程是连续的,也可以是时断时续的。Session 是一种服务器端的机制,Session 对象用来存储特定用户会话所需的信息。Session 由服务端生成,并且保存在服务器端的内存或者缓存中,也可以是硬盘或数据库中。
📌提示
:使用 Session 需要在浏览器客户端中启动 Cookie,且需要使用 Cookie 中存储 Sessionid。Sessionid 是服务器返回给浏览器的唯一标识。
理解Session的作用
📑当用户使用浏览器访问服务器的时候,服务器就会为该浏览器建立一个 Session 会话控制。在创建这个 Session 时候,服务器通过 Sessionid 来检查是否该浏览器是第一次方访问。若是初次访问,则服务器会为客户端浏览器创建一个 Session 并且生成一个 Sessionid。通过 HttResponse 响应将 Sessionid 发送给浏览器,浏览器接收后会将这个具有标识性的 Sessionid 保存在 Cookie 中,再次访问的时候由 Cookie 携带着它去访问服务器。
📑Sessionid 本质上是一个加密的字符串,具有唯一性与不可重复性。这就相当于服务器给浏览器发放了一张令牌或者通行证,告诉浏览器下次你再访问我的时候们,拿着通行证来。这就解决了 HTTP 的无状态,无记忆的问题,当再次访问服务器时就可以实现用户的免登录了。Session 的典型应用场景分别是:1. 判断用户是否登录;2. 实现商城的购物车的功能。
📌提示
:不同的浏览器在服务端都有独立的 Session,它们与请求者之间是一一对应的关系。
Session配置
📑📑在 Django 的 settings.py 配置文件中,找到 INSTALLED_APPS 的列表并启用 Session 应用,同时在 MIDDLEWARE_CLASSES 中启用 SessionMiddleware 中间件。默认情况下上述两者都是开启状态。
Session的基本操作
📑📑Session可以用类似于字典的方式进行操作,并且Session只能够存储序列化的数据,例如字典或者列表等。
📌下面我们介绍 Session 的一些常规操作,如下所示:
#保存session的值到服务器
request.session[KEY] = VALUE
#获取session的值
VALUE = request.session[KEY]
VALUE = request.session.get('KEY', 缺省值)
#删除session的值
del request.session[KEY]
request.session.flush()#删除所有session
Session在settings.py中的配置
SESSION_COOKIE_AGE
和SESSION_EXPIRE_AT_BROWSER_CLOSE
都是Django中用来设置Session过期时间的设置,具体作用如下:
-
SESSION_COOKIE_AGE
是指Session的生存时间,以秒为单位。当用户长时间不操作或达到设定的时间后,Session将失效并被清除。默认情况下,在Django中,Session是永久存在的,也就是说直到关闭浏览器或清除Cookie,Session才会失效。如果想要让Session在一段时间后自动失效,可以设置SESSION_COOKIE_AGE
。 -
SESSION_EXPIRE_AT_BROWSER_CLOSE
是指Session的过期时间是在浏览器关闭时自动过期。即在浏览器关闭时清除Session,而不是在时间间隔过期。如果设置了该选项,则SESSION_COOKIE_AGE
设置将被忽略,因为Session会在浏览器关闭时立即过期。
📌这两个设置需要写在Django的settings.py文件中,可以按照如下方式进行设置:
# 设置 Session 的 Cookie 生命周期为 1 小时
SESSION_COOKIE_AGE = 3600
#默认值2周的时间
SESSION_COOKIE_AGE = 60 * 60 * 24 * 7 * 2
# 设置 Session 在浏览器关闭时过期
SESSION_EXPIRE_AT_BROWSER_CLOSE = True # 它的模认值是 False,即表示不开启。
以上设置示例中,
SESSION_COOKIE_AGE
设置了Session的生存时间为1小时,SESSION_EXPIRE_AT_BROWSER_CLOSE
设置了Session在浏览器关闭时过期。将这些设置添加到Django的settings.py文件中,可以全局控制Session的行为,并为应用程序提供更好的安全性和性能。
Cookie和Session的区别
📑📑通过这两节的内容,我们介绍了 Cookie 和 Session,下面我们进行一下总结,帮助大家更好的理解这两种状态保持机制。我们从它们的不同点着手开始分析。
-
存储位置与存储方式不同
- 它们各自的存放位置不同 。Cookie 保存在客户端,而 Session 保存在服务端。
-
安全性两者不同
- 我们从安全角度进行考虑,Cookie 是存储在客户端浏览器中的,所以对于用户是可见的。利用一些脚本可以轻松获得浏览器中的所有 Cookie,从而带来安全隐患,所以对于敏感信息不要写在 Cookie 中,如用户的账号密码等,而 Session 是存储在服务器上的,不存在敏感信息泄露的问题。
-
对于服务器压力不同
- 最后对服务器造成的压力不同,Session 是保管在服务器端的,每个用户都会创建一个独立的 Session。如果此时发起求的客户端很多,也就是说平法访问的数量较多,那么此时就会产生许多的 Session,也将占用计算机大量内存空间。但是对于 Cookie 来说就无须担心,因为它保管在浏览器中,不占用服务器资源。所以针对这种情景应该选用 Cookie。
Django HTML表单实战
📑📑如何使用 Django 实现用户的登录以及退出功能,希望大家通过这两节内容的学习,学会总结思路,把这个开发功能的过程反复练习,这样才能够更好的理解 Django 框架,而且在以后 Web 开发的道路上也会对自己大有裨益。
HTML表单实现用户的登录
-
HTML表单编写前端页面
可以新建一个app(应用)
📌 在templates\user 目录下新建 login.html 文件。并在其中编写如下代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登录页</title>
<style>
#pwd input{
margin-left:23px
}
</style>
</head>
<body>
<form action="/user/login/" method="post">
<!--传统的html登录表单-->
<p>
用户名: <input type="text" name="username" value="{{ username }}">
<span> {{ error }}</span>
</p>
<p id=pwd>
密码: <input type="text" name="password" value="{{ password }}">
</p>
<p>
记住用户名: <input type="checkbox" name="isSaved">
</p>
<p>
<input type="submit" value="登录">
</p>
</form>
</body>
</html>
上述代码理解起来非常的通俗易懂,但是不难发现我们在其中新增了一个记住用户名的小功能,没错它就是通过 Cookies 实现的。
- 编写视图函数
📌 在 user\views.py 中编写视图层用户登录逻辑代码,如下所示:
#用户的登录逻辑处理
def login_view(request):
#处理GET请求
if request.method == 'GET':
#1, 首先检查session,判断用户是否第一次登录,如果不是,则直接重定向到首页
if 'username' in request.session: #request.session 类字典对象
return HttpResponseRedirect('/index/allbook')
#2, 然后检查cookie,是否保存了用户登录信息
if 'username' in request.COOKIES:
#若存在则赋值回session,并重定向到首页
request.session['username'] = request.COOKIES['username']
return HttpResponseRedirect('/index/allbook')
#不存在则重定向登录页,让用户登录
return render(request, 'user/login.html')
# 处理POST请求
elif request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
m = hashlib.md5()
m.update(password.encode())
password_m = m.hexdigest()
#判断输入是否其中一项为空或者格式不正确
if not username or not password:
error = '你输入的用户名或者密码错误 !'
return render(request, 'user/login.html', locals())
#若输入没有问题则进入数据比对阶段,看看已经注册的用户中是否存在该用户
users = User.objects.filter(username=username, password=password_m)
# 由于使用了filter, 所以返回值user是一个数组,但是也要考虑其为空的状态,即没有查到该用户
if not users:
error = '用户不存在或用户密码输入错误!!'
return render(request, 'user/login.html', locals())
# 返回值是个数组,并且用户名具备唯一索引,当前用户是该数组中第一个元素
users = users[0]
request.session['username'] = username
response = HttpResponseRedirect('/index/allbook')
#检查post 提交的所有键中是否存在 isSaved 键
if 'isSaved' in request.POST.keys():
#若存在则说明用户选择了记住用户名功能,执行以下语句设置cookie的过期时间
response.set_cookie('username', username, 60*60*24*7)
return response
📌 完成视图层代码后,记得要配置路由映射关系,如下所示:
from django.urls import path
from user import views
urlpatterns=[
# path('reg/',views.reg_view),
path('login/',views.login_view)
]
实现用户的退出功能
📌用户的退出功能相对来说要简单的多,通过下面代码就可以实现:
def logout_view(request):
#实现退出功能
#删除session
if 'username' in request.session:
del request.session['username']
resp = HttpResponseRedirect('/user/index')
#删除cookie
if 'username' in request.COOKIES:
resp.delete_cookie('username')
return resp
#编写视图函数映射关系
urlpatterns = [
#http://127.0.0.1:8000/user/logout
path('logout/', views.logout_view)
]
大家可以自行编写一个简单的网站首页,我们知道退出功能的 button 都会显示在首页边角位置,所以只需要将退出功能的 url 关联到
<a>
标签的 href 属性即可实现点击退出的功能了。