前言
这几年一直在it行业里摸爬滚打,一路走来,不少总结了一些python行业里的高频面试,看到大部分初入行的新鲜血液,还在为各样的面试题答案或收录有各种困难问题
于是乎,我自己开发了一款面试宝典,希望能帮到大家,也希望有更多的Python新人真正加入从事到这个行业里,让python火不只是停留在广告上。
微信小程序搜索:Python面试宝典
或可关注原创个人博客:https://lienze.tech
也可关注微信公众号,不定时发送各类有趣猎奇的技术文章:Python编程学习
Cookie
在django
的代码中,我们可以使用一些提供Response
响应的类,如:HttpResponse
,redirect
等实例的内置set_cookie
函数来进行django
项目中的Cookie
设置
set_cookie(key, value='', max_age=None, expires=None, path='/',domain=None, secure=False, httponly=False)
'''
key: Cookie的key值,未来通过该key值获取到对应设置好的Cookie。
value='': 对应Cookie的key值的value,比如: set_cookie(key='value',value='shuai')
max_age=None: Cookie生效的时间,单位为秒,如果Cookie值只持续在客户端浏览器的会话时长,那么这个值应该为None。存在该值时,expires会被计算得到。
expires=None: Cookie具体过期日期,是一个datetime.datetime对象,如果该值存在,那么max_age也会被计算得到
path='/': 指定哪些url可以访问到Cookie,默认/为所有。
domain=None: 当我们需要设置的为一个跨域的Cookie值,那么可以使用该参数,比如: domain='.test.com',那么这个Cookie值可以被www.test.com、bbs.test.com等主域名相同的域所读取,否则Cookie只被设置的它的域所读取。为None时,代表当前域名下全局生效。
secure=False: https加密传输设置,当使用https协议时,需要设置该值,同样的,如果设置该值为True,如果不是https连接情况下,不会发送该Cookie值。
httponly=False: HTTPOnly是包含在HTTP响应头部中Set-Cookie中的一个标记。为一个bool值,当设置为True时,代表阻止客户端的Javascript访问Cookie。这是一种降低客户端脚本访问受保护的Cookie数据风险的有效的办法
'''
import datetime
current_time = datetime.datetime.now() # 当前时间
expires_time = current_time + datetime.timedelta(seconds=10) # 向后推延十秒
set_cookie('key','value',expires=expires_time) #设置Cookie及对应超时时间
设置COOKIE
实现一下COOKIE
的设置
from django.shortcuts import render,HttpResponse
# Create your views here.
def set_cookie(request):
# 在HTTPResponse部分设置COOKIE值
cookie_reponse = HttpResponse('这是一个关于cookie的测试')
cookie_reponse.set_cookie('test','hello cookie')
return cookie_reponse
以上视图函数返回一个HttpResponse
对象,并在该对象中集成COOKIE
值的设定,设置key
值为test
,value
值为hello cookie
获取COOKIE
再来简单的实现一下COOKIE
的获取
def get_cookie(request):
# 获取cookie值,从request属性中的COOKIE属性中
cookie_data = request.COOKIES.get('test')
return HttpResponse('Cookie值为:%s' % cookie_data)
Cookie
值存储在,request
中的COOKIES
属性中
并且该属性获取到的结果与python中的字典类似,直接通过内置函数get
获取即可
删除COOKIE
这里通过该视图函数路由进行COOKIE的删除
def delete_cookie(request):
response = HttpResponseRedirect('/check_cookie/')
response.delete_cookie('test')
return response
delete_cookie(key, path='/', domain=None)
在Cookie
中删除指定的key
及对应的value
,如果key
值不存在,也不会引发任何异常。
由于Cookie
的工作方式,path
和domain
应该与set_cookie
时使用的值相同,否则Cookie
值将不会被删除
通过response
相应类的delete_cookie
方法,本来应该在会话结束之后才消失的Cookie
值,现在已经被直接删除掉。后台中通过Request
中的Cookie
字典获取到值也为None
不要忘记字典的get,获取不到结果时,返回None
但是,现在还有一个问题,我们在用户浏览器存储的Cookei值为明文,具有极大的安全隐患,django也提供了支持签证的Cookie值存储及获取方式
防止篡改COOKIE
通过set_signed_cookie
函数进行持有签名的COOKIE
值设置,避免用户在客户端进行修改
要记得,这个函数并不是对COOKIE
值进行加密
HttpResonse.set_signed_cookie(key, value, salt='', max_age=None,
expires=None, path='/', domain=None, secure=None, httponly=True)
# 为cookie值添加签名,其余参数与set_cookie相同
Request.get_signed_cookie(key, salt='', max_age=None)
# 从用户请求中获取通过salt盐值加了签名的`Cookie`值
这里的salt
要与之前存储时使用的salt
值相同才可以解析出正确结果。
还要注意的是,如果对应的key值不存在,则会引发KeyError
异常,所以要记得异常捕获来确定是否含有Cookie
值
def check_salt_cookie(request):
try:
salt_cookie = request.get_signed_cookie(key='salt_cookie',salt='nice')
except KeyError: #获取不到该key值的Cookie
response = HttpResponse('正在设置一个salt Cookie值')
response.set_signed_cookie(key='salt_cookie',salt='nice',value='salt_cookie')
return response
else: #获取到了对应key值,展示到新的HttpResonse中
return HttpResponse('获取到的salt Cookie值:%s' % salt_cookie)
第一次访问的时候,还没有加Cookie
值,所以我们在获取的时候会抛出KeyError
异常
此时捕获异常,并且设置Cookie
即可;
再次刷新的时候,因为这里已经给出了Cookie
值,则不会引发异常,会在页面中展示获取到的加盐Cookie
Session
虽然说有了Cookie
之后,我们把一些信息保存在客户端浏览器中,可以保持用户在访问站点时的状态,但是也存在一定的安全隐患,Cookie
值被曝露,Cookie
值被他人篡改,等等。我们将换一种更健全的方式,也就是接下来要说的Session
。
Session
在网络中,又称会话控制,简称会话。用以存储用户访问站点时所需的信息及配置属性。当用户在我们的Web
服务中跳转时,存储在Session
中的数据不会丢失,可以一直在整个会话过程中存活。
在
django
中,默认的Session
存储在数据库中session
表里。默认有效期为两个星期。
session创建流程
- 客户端访问服务端,服务端为每一个客户端返回一个唯一的
sessionid
,比如xxx
。 - 客户端需要保持某些状态,比如维持登陆。那么服务端会构造一个
{sessionid: xxx }
类似这样的字典数据加到Cookie
中发送给用户。注意此时,只是一个随机字符串,返回给客户端的内容并不会像之前一样包含实际数据。 - 服务端在后台把返回给客户端的
xxx
字符串作为key
值,对应需要保存的服务端数据为一个新的字典,存储在服务器上,例如:{xxx : {id:1}}
之后的一些客户端数据获取,都是通过获取客户端向服务端发起的HttpRequest
请求中里Cookie
中的sessionid
之后,再用该sessionid
从服务端的Session
数据中调取该客户端存储的Session
数据
- 注意:补充说明,默认存储在数据库的
Session
数据,是通过base64
编码的,我们可以通过Python
的base64
模块下的b64decode()
解码得到原始数据
整个过程结束之后:客户端浏览器存储的其实也只是一个识别会话的随机字符串(xxx)
而服务器中是通过这个随机的字符串(xxx:value)
进行真正的存储
Session
的使用必须在Settings
配置下
INSTALLED_APPS = (
...
'django.contrib.sessions',
...
)
MIDDLEWARE_CLASSES = (
'django.contrib.sessions.middleware.SessionMiddleware',
...
)
当settings.py
中SessionMiddleware
激活后
在视图函数的参数request
接收到的客户端发来的HttpResquest
请求对象中都会含有一个session
属性
这个属性和之前所讨论的Cookie
类似,是一个类字典对象,首先支持如下常用字典内置属性
获取Session
session_data = request.session.get(Key)
session_data = request.session[Key]
在Session
中获取对应值,get
方法获取时,如不存在该Key
值,不会引发异常,返回None
而第二种直接通过get方法获取,如Key
值不存在,引发KeyErro
删除Session
del request.seesion[Key]
# 删除对应session,Key值不存在时,引发KeyError
request.session.clear()
# 清空Session中的所有数据。这里客户端还会保留sessionid;
# 只不过在服务端sessionid对应的数据没有了
request.session.flush()
# 直接删除当前客户端的的Seesion数据。这里不光服务端sessionid对应的数据没有了,客户端的`sessionid`也会被删除
设置有效期
request.session.set_expiry(value)
# 设置Session的有效时间
'''
value: 有效时间。
- 为整数时: 将在value为秒单位之后过期
- 为0时: 将在用户关闭浏览器之后过期。
- 为None时: 使用全局过期的设置,默认为两个星期,14天。
- 为datetime时: 在这个指定时间后过期
'''
request.session.get_expiry_age()
# 返回距离过期还剩下的秒数
request.session.clear_expired()
# 清除过期的Session会话
- session示例
from django.shortcuts import render,HttpResponse
import datetime
def set_session(request):
if request.session.get('test_id'):
session_data = request.session.get('test_id')# 用户拿到的的session随机字符串
session_key = request.session.session_key # 获取客户端浏览器中的SessionID值
session_expire = request.session.get_expiry_age()
now = datetime.datetime.now()
expire_time = now + datetime.timedelta(seconds=session_expire)
response = '<div>SessionID : %s</div>' % session_key + \
'<div>Session : %s</div>' % session_data + \
'<div>ExpireTime : %s</div>' % expire_time
return HttpResponse(response)
else:
request.session['test_id'] = 'TEST'
request.session.set_expiry(None)
return HttpResponse('已设置好Session')
用户在第一次访问时,会走else
分支,此时还没有任何服务端的Session
及客户端的Cookie
值设定
那么我们会通过request.session[Key]
的方式来设置一个Session
值,值为TEST
当用户第二次访问时将展示出所设置好的Session值及在客户端浏览器中存储的sessionid
在编写一个删除Session
的视图函数吧
def delete_session(request):
if request.session.get('test_id'):
del request.session['test_id']
return HttpResponse('Session被删了')
else:
return HttpResponse('目前没有任何需要删除的session')
这里温柔的使用del request.session[Key]
的方式来进行Session
的删除
如果存在对应test_id
的Session
值则删除,反之返回一个字符串
Session删除总结
使用的是del
的针对性删除方式,这样不会将整个客户端的session
删除掉
使用request.session.clear()
,只是清空了服务端Session
中的数据,但是客户端的Cookie
中还会保存sessionid
,只不过这个值对应的字符串所对应的用户数据是一个空
使用request.session.flush()
,那么客户端Cookie
中保存的sessionid
首先会被删除,其次服务端通过sessionid
值保存的用户数据也会被全部删除。