011-Djang的cookie和session
————————————————————-cookie与session———————————————————-
前面已经说过http协议无法保存状态,但是实际使用场景,我们又却要保存状态,因此cookie就诞生了,会话跟踪技术。
定义:保存在浏览器本地的key value(键值对)。类似python的字典。翻译成中文就是小饼干的意思。
工作原理:由服务器产生内容,浏览器收到响应后保存在本地,当浏览器再次访问时,浏览器会自动携带cookie,服务器就能判断这个是谁了。
发展:虽然一定程度上解决了’保持登录的状态’,但是cookie本身最大只支持4096b,而且cookie是保存在浏览器本地的,有些用户敏感内容、私密信息存起来也不好,随时可拦截和窃取。因此就需要一种新的东西,
支持更大的字节。且不是保存在浏览器本地,而是保存在服务器。有较高的安全性,它就是session。
注意:
session和cookie不限于django。不限于语言和框架。其实是共通性的东西。
不同浏览器无法共享cookie,也就是换个浏览器,cookie是不一样的。
多次登录,同一个浏览器的cookie会覆盖之前的记录
先来写一个cookie版的登录
视图部分:
1 def login(request): 2 if request.method == "POST": 3 user = request.POST.get('user') # 获取用户名 4 pwd = request.POST.get('pwd') # 获取密码 5 user = models.UserInfo.objects.filter(name=user, pwd=pwd).first() # 数据库查找 6 7 # 如果有这个用户 8 if user: 9 # 登录成功 10 # 创建响应对象:HttpResponse() or render(request,...) or redirect() 三个都可以 11 response = HttpResponse('ok') 12 13 # 设置cookie 14 response.set_cookie('is_login', True) # 浏览器保存形式:{"is_login":true} 15 response.set_cookie('user', user.name, ) # 浏览器保存形式:{"user":用户的名字} 16 return response 17 18 return render(request, 'login.html')
模版部分:
1 <!DOCTYPE html> 2 <html lang="zh_CN"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta http-equiv="x-ua-compatible" content="IE=edge"> 6 <meta name="viewport" content="width=device-width, initial-scale=1"> 7 <title>Title</title> 8 </head> 9 <body> 10 11 <form action="" method="post"> 12 {% csrf_token %} 13 用户名:<input type="text" name="user"> 14 密码:<input type="password" name="pwd"> 15 <input type="submit" value="登录"> 16 17 </form> 18 </body> 19 </html>
再写一个index视图。如果不设置cookie的话,用户是可以直接访问的。
视图部分:
1 def index(request): 2 # 获取cookie 3 is_login = request.COOKIES.get('is_login') 4 name = request.COOKIES.get('user') 5 6 # 如果is_login为空,重定向到login页面 7 if not is_login: 8 return redirect('/login/') 9 # 登录成功就返回index页面 10 return render(request, 'index.html', {"username": name})
模版部分:
1 <!DOCTYPE html> 2 <html lang="zh_CN"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta http-equiv="x-ua-compatible" content="IE=edge"> 6 <meta name="viewport" content="width=device-width, initial-scale=1"> 7 <title>Title</title> 8 </head> 9 <body> 10 11 <h1>this is index</h1> 12 <h3>Hello {{ username }}</h3> 13 <p>上次登录时间:{{ last_time }}</p> 14 15 <a href="/logout_session/">注销</a> 16 </body> 17 </html>
先不登录访问index一下:
可以看到自动跳转到login页面了。因为没登陆,获取不到cookie。
现在登陆:
登录成功后
可以看到浏览器保存了cookie
再次访问index
写注销视图logout
1 def logout(request): 2 response = redirect('/login/') 3 # 清除cookie 4 response.delete_cookie(key='is_login') 5 return response
访问/logout/后,会自动跳转到logim登录页面
再此访问index。cookie清理了。会自动跳转到login登录。
session版登录
视图部分:
基本和cookie一样就是设置的方式不一样
def login_session(request): if request.method == 'POST': username = request.POST.get('user') pwd = request.POST.get('pwd') user = models.UserInfo.objects.filter(name=username, pwd=pwd).first() if user: request.session['is_login'] = True request.session['username'] = username ''' 三步: 如果已经访问过一次,有session_id就是更新操作。并不是登录一次创建一次,并不是创建 1、服务器生成一个随机字符串xxx 2、response.set_cookie('session_id','xxx') 3、在django_session表中创建一条记录: session-key session-data 过期时间 xxx {'is_login':True,'username':username} ''' return HttpResponse('登录成功') return render(request, 'login.html')
index视图
1 def index_session(request): 2 is_login = request.session.get('is_login') 3 print(is_login) 4 ''' 5 1、request.COOKIES.get('session_id') # 得到随机字符串 6 2、在django-session表中过滤记录 7 obj = django-session.objects.filter(session-key=xxx).first() 8 3、obj.session-data.get('is_login') 9 ''' 10 if is_login: 11 username = request.session.get('username') 12 last_time = request.session.get('last_time') 13 return render(request, 'index.html', {"username": username, "last_time": last_time}) 14 return render(request, 'login.html')
logout注销视图
1 def logout_session(request): 2 response = redirect('/login_session/') 3 request.session.flush() # 删除当前会话的数据和cookie 4 return response
总结:
cookie: 1、设置cookie response.set_cookie(key,value) 2、读取cookie request.COOKIES.get(key) 3、删除cookie response.delete_cookie(key) 设置和删除都是response 读取是request session 1、设置:request.session[key]=value 2、读取:request.session.get(key) 3、删除:request.session.flush() 都是request