DAY84-Django框架(十四) cookie and session 一、cookie 二、session 三、cookie与session的区别
1.cookie
cookie 是一个非常具体的东西,指的就是浏览器里面能永久存储的一种数据,仅仅是浏览器实现的一种数据存储功能。
2.原理
cookie由服务器生成,发送给浏览器,浏览器把cookie以key:value形式保存到浏览器客户端上,下一次请求同一网站时会把该cookie发送给服务器。由于cookie是存在客户端上的,所以浏览器加入了一些限制确保cookie不会被恶意使用,同时不会占据太多磁盘空间,所以每个域的cookie数量是有限的。
3.基本使用
#设置cookie,模拟服务器往浏览器发送cookie
def set_cookie(request):
obj = HttpResponse('set_cookie')
obj.set_cookie('name','xcq')
obj.set_cookie('name','lqz')#对同一个key的cookie设置value,会覆盖
return obj
#由于之前的默认设置,是在同一域名中,所以request可以拿到本地域名中的所有cookie
def get_cookie(request):
print(request.COOKIES)#以字典形式接受
print(request.COOKIES['name'])
obj = HttpResponse('get_cookie')
return obj
4.参数
#设置cookie
set_cookie(
key, #键
value='', #值
max_age=None, #超时时间,以秒为单位,默认None,表示这个cookie会持续到浏览器关闭为止
expires=None, #超时时间,与max_age一样,传一个datatime对象
path='/', #Cookie生效的路径,默认为‘/’,表示根路径可以被任何URL的页面访问
domain=None, #Cookie生效的域名,默认为None,表示cookie只能由设置它的站点读取
secure=False, #默认是false,设置成True浏览器将通过HTTPS来回传cookie
httponly=False #默认是false,设置成True就无法被JavaScript获取
):
5.加盐cookie
加盐是为了提高cookie的安全性,因为cookie是明文传递的
def set_cookie(request):
obj = HttpResponse('set_cookie')
obj.set_signed_cookie('name','xcq',salt='123')
#密钥为123
#加盐之后,会在xcq之后生成一串随机字符
return obj
def get_cookie(request):
# print(request.get_signed_cookie('name'))#不写密钥会报错
print(request.get_signed_cookie('name',salt='123'))
#想要获得原先的cookie值,要加上密钥
obj = HttpResponse('get_cookie')
return obj
6.删除cookie
def del_cookie(request):
obj = HttpResponse('del_cookie')
obj.delete_cookie('name')#只能删除指定key的cookie,无法全部删除
return obj
7.在浏览器中查看
浏览器中按F12,点network---cookies就能看到
8.简单实例
要求:
1.做一个简单的登录
2.做一个装饰器:点击别的页面,强制进入登录页面,登陆成功后跳转回之前的页面
def login_auth(func):
def inner(request, *args, **kwargs):
#拿到被装饰的页面路径
url = request.get_full_path()
if request.COOKIES.get('is_login'):
res = func(request, *args, **kwargs)
return res
else:
#把被装饰的页面路径通过get传递给登陆页面
return redirect('/login/?next=%s' % url)
return inner
def login(request):
if request.method == 'GET':
return render(request, 'login.html')
if request.method == 'POST':
name = request.POST.get('name')
pwd = request.POST.get('pwd')
if name == 'xcq' and pwd == '123':
#登陆页面通过GET拿到之前的路径
url = request.GET.get('next')
if url:
#登陆成功且是跳转的登陆,就跳转到之前的页面
obj = redirect(url)
else:
obj=HttpResponse('主页')
obj.set_cookie('is_login', 'True')
obj.set_cookie('username', name)
return obj
return render(request, 'login.html')
@login_auth
def shopping(request):
return HttpResponse('购物界面')
@login_auth
def order(request):
return HttpResponse('订单界面')
二、session
1.session
session 从字面上讲,就是会话。这是为了解决cookie不安全而出现的
2.原理
服务器为了知道当前发请求给自己的是谁,服务器就要给每个客户端分配不同的“身份标识”,然后客户端每次向服务器发请求的时候,都带上这个“身份标识”,服务器就知道这个请求来自于谁了。至于客户端怎么保存这个“身份标识”,可以有很多种方式,对于浏览器客户端,大家都默认采用 cookie 的方式。
服务器使用session把用户的信息临时保存在了服务器上,用户离开网站后session会被销毁。这种用户信息存储方式相对cookie来说更安全,可是session有一个缺陷:如果web服务器做了负载均衡,那么下一个操作请求到了另一台服务器的时候session会丢失。
3.基本使用
#设置session
def set_session(request):
request.session['name']='xcq'
# request.session['name']='lqz' #对同一个key设置value,会覆盖
request.session['age']=18
# request.session.setdefault('age',18)#如果已存在age字段,则不设置
#设置session,其内部发生了三件事
# 1.根据其浏览器客户端,生成了唯一的随机字符串sessionid
# 2.去Django的内部数据库django_session存储
# session_key(随机字符串) 值(字典形式) 超时时间()
# sessionid {'name':'xcq','age':18} 默认当前时间过两周
# 3.设置了一个cookie:set_cookie('sessionid',随机字符串),浏览器只有通过sessionid来服务器找到对应的数据
request.session.set_expiry(0)
#如果value是个整数,session会在些秒数后失效。
#如果value是个datatime或timedelta,session就会在这个时间后失效。
#如果value是0, 用户关闭浏览器session就会失效。
#如果value是None, session会依赖全局session失效策略。
return HttpResponse('set_session')
#获取session
def get_session(request):
# 获得session数据时:
# 1.在cookie中获得sessionid对应的随机字符串
# 2.去django_session中根据唯一sessionid获取对应数据
# 拿到key对应的value,没有则报错
print(request.session['name'])
# 拿到value,没有不会报错
print(request.session.get('age'))
# 拿到所有的key
print(request.session.keys())
# 拿到所有的value
print(request.session.values())
# 拿到字典形式
print(request.session.items())
# 拿到sessionid
print(request.session.session_key)
return HttpResponse('get_session')
#删除session
def del_session(request):
#删除对应的数据
del request.session['name']
#删除数据库的session
request.session.delete()
#删除数据库和cookie的session
request.session.flush()
# 将所有Session失效日期小于当前日期的数据删除
request.session.clear_expired()
print(request.session.items())
return HttpResponse('del_session')
4.setting中的session设置
1. 数据库Session
SESSION_ENGINE = 'django.contrib.sessions.backends.db' # 引擎(默认)
2. 缓存Session
SESSION_ENGINE = 'django.contrib.sessions.backends.cache' # 引擎
SESSION_CACHE_ALIAS = 'default' # 使用的缓存别名(默认内存缓存,也可以是memcache),此处别名依赖缓存的设置
3. 文件Session
SESSION_ENGINE = 'django.contrib.sessions.backends.file' # 引擎
SESSION_FILE_PATH = None # 缓存文件路径,如果为None,则使用tempfile模块获取一个临时地址tempfile.gettempdir()
4. 缓存+数据库
SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db' # 引擎
5. 加密Cookie Session
SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies' # 引擎
其他公用设置项:
SESSION_COOKIE_NAME = "sessionid" # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串(默认)
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 = 1209600 # Session的cookie失效日期(2周)(默认)
SESSION_EXPIRE_AT_BROWSER_CLOSE = False # 是否关闭浏览器使得Session过期(默认)
SESSION_SAVE_EVERY_REQUEST = False # 是否每次请求都保存Session,默认修改之后才保存(默认)
5.基于session写一个CBV的登陆装饰器
#重写父类的装饰器
class Login_user(View):
#dispatch会对类里的所有方法有效
def dispatch(self, request, *args, **kwargs):
url = request.get_full_path()
if request.session.get('is_login'):
res = super().dispatch(request, *args, **kwargs)
return res
else:
return redirect('/login/?next=%s' % url)
class Login(View):
def get(self, request):
return render(request, 'login.html')
def post(self, request):
name = request.POST.get('name')
pwd = request.POST.get('pwd')
if name == 'xcq' and pwd == '123':
url = request.GET.get('next')
if url:
obj = redirect(url)
else:
obj = HttpResponse('主页')
request.session['is_login'] = True
return obj
return render(request, 'login.html')
class Shopping(Login_user):
def get(self, request):
return HttpResponse('购物界面')
class Order(Login_user):
def get(self, request):
return HttpResponse('订单界面')
方法二
from django.utils.decorators import method_decorator
def login_auth(func):
def inner(request, *args, **kwargs):
url = request.get_full_path()
if request.COOKIES.get('is_login'):
res = func(request, *args, **kwargs)
return res
else:
return redirect('/login/?next=%s' % url)
return inner
class Login(View):
def get(self, request):
return render(request, 'login.html')
def post(self, request):
name = request.POST.get('name')
pwd = request.POST.get('pwd')
if name == 'xcq' and pwd == '123':
url = request.GET.get('next')
if url:
obj = redirect(url)
else:
obj = HttpResponse('主页')
request.session['is_login'] = True
return obj
return render(request, 'login.html')
#@method_decorator(指定装饰器,name=制定方法),如果没有写name=,那也会对所有方法有效
@method_decorator(login_auth,name='get')
class Shopping(View):
def get(self, request):
return HttpResponse('购物界面')
@method_decorator(login_auth,name='get')
class Order(View):
#也可以写在方法上,只会装饰这个方法
@method_decorator(login_auth)
def get(self, request):
return HttpResponse('订单界面')
三、cookie与session的区别
cookie 和session 的区别:
- cookie数据存放在客户的浏览器上,session数据放在服务器上。
- cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗,考虑到安全应当使用session。
- session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能考虑到减轻服务器性能方面,应当使用COOKIE。
- 单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。
打个比方,浏览器客户端是我本人,而服务器就是银行。
那么cookie就像是我手里存折,存折上面会记录你每一次的存取钱的记录,而cookie就是记录在浏览器上,我不用去问银行,就知道所有的记录;
但session就像是银行卡,我本人手里只有银行卡和唯一的识别卡号,而所有关于我的数据记录都在银行里面,我只能通过卡号去银行(服务器)查询我的卡号所对应的所有的操作记录。