这一篇教程,我们一起来了解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”比较常用的参数包括:
示例代码:
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”:
这里只为大家介绍默认的基于数据库的“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/