Cookie、Session和自定义分页
Cookie
cookie 的由来
Http请求是无状态的.
无状态的意思就是每次请求都是独立的, 他的执行情况和结果与前面的请求和之后的请求都无直接联系, 他不会受前面的请求情况直接影响, 他也不会直接影响后面的请求相应情况.
对于服务器而言每次请求都是全新的请求. 状态可理解为客户端与服务端某次会话中产生的数据.那么无状态就不会保留这些数据.如果会话中的数据我们需要保留下来,也就是说要"保持状态", 因此就产生了 Cookie .
什么是 Cookie
Cookie 具体指的是一段小信息,他是服务器发送出来存储在浏览器上的一组键值对,下次访问服务器时浏览器会自动携带着这些键值对, 以便服务器从中提取有用的信息.
Cookie 的原理
Cookie 的工作原理是: 有服务器产生内容, 浏览器收到请求后保存在本地, 当浏览器再次访问时, 浏览器会自动带上 Cookie ,这样服务器就能通过 Cookie的内容来判断这个链接的信息.
Django 中操作 Cookie
获取 Cookie
request.COOKIES['key'] request.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age=None)
参数:
- default: 默认值
- salt: 加密盐
- max_age: 后台控制过期时间
设置 Cookie
# 设置 cookie
rep = redirect('/home/')
# rep = redirect('/home/')
rep.set_cookie('key','value') # 告诉浏览器在自己本地保存一个键值对.
rep.ser_signed_cookie(key,value,salt='加密盐',max_age=None......)
参数:
- key: 键
- value='': 值
- max_age=None: 超时时间.
- expires=None,超时时间(IE requires expires, so set it if hasn't been already.)
- path='/',: Cookie生效路径.
- domain: None,Cookie生效的域名..
- secure=False,Https传输
删除 Cookie
ret = redirect('/login/')
ret.delete_cookie('key')
return ret
Cookie 版登录验证
from functools import wraps # cookie 登录验证装饰器 def check_login(func): @wraps(func) def inner(request,*args,**kwargs): # 先做 Cookie 验证 cookie_value = request.COOKIES.get('kiis') if cookie_value == "abcdefg": rep = func(request,*args,**kwargs) return rep else: return_url = request.path_info print(return_url) return redirect('/login/?return_Url={}'.format(return_url)) return inner # 登录代码 class login(views.View): def get(self,request): rep = render(request, 'login.html') return rep def post(self,request): print(request.POST) username = request.POST.get('userName') pwd = request.POST.get('passWord') is_user = UserInfo.objects.filter(username=username,password=pwd) if is_user: # 设置 cookie rep = redirect('/home/') rep.set_cookie('kiis','abcdefg') # 告诉浏览器在自己本地保存一个键值对. return rep else: return render(request, 'login.html',{'msg':'用户名或密码错误!'}) # 注销 @check_login def home(request): if request.method == "POST": ret = redirect('/login/') ret.delete_cookie('kiis') return ret return render(request, 'home.html')
Session
Session的由来
Cookie 虽然在一定程度上解决了 "保持状态" 的需求, 但是由于 Cookie 本身支持 4096 字节,以及 Cookie 本身保存在客户端, 可能被拦截或窃取, 因此就需要一种新技术,他能支持更多字节,并且保存在服务器,又比较高的安全性,这就是Session.
Django中Session相关方法
常用方法
# 设置 session
request.session['k1']=value
# 获取 session
request.session.get('k1',None)
# 存在则不设置
request.sssion.setdefault('k1',123)
# 删除 session
del request.session['key1']
# 删除当前的会话数据并删除会话的 Cookie
request.session.flush()
其他方法
# 获取所有的 键, 值, 键值对
request.session.keys()
request.session.values()
request.session.items()
request.session.iterkeys()
request.session.itervalues()
request.session.iteritems()
# 获取会话 session 的key
request.session.session_key
# 将所有session失效日期小于当前的数据删除
request.session.clear_expired()
# 检查会话 session 的key 在数据库中是否存在
request.session.exists('session_key')
# 删除当前会话的所有 session 数据
request.session.delete()
# 设置会话 session 和 cookie 的超时时间
request.session.set_expiry(value)
* 如果value是个整数,session会在些秒数后失效。
* 如果value是个datatime或timedelta,session就会在这个时间后失效。
* 如果value是0,用户关闭浏览器session就会失效。
* 如果value是None,session会依赖全局session失效策略。
Session解析流程

Session版本登录验证
1 # 设置 session 2 class login(views.View): 3 def get(self,request): 4 rep = render(request, 'login.html') 5 return rep 6 def post(self,request): 7 print(request.POST) 8 username = request.POST.get('userName') 9 pwd = request.POST.get('passWord') 10 # 获取用户是否勾选七天免登录 11 remember_7 = request.POST.get('check1',None) 12 user_obj = UserInfo.objects.filter(username=username,password=pwd).first() 13 if user_obj: 14 # 获取用户上个页面跳转的 地址 如果没有获取到则设置 默认值 15 return_url = request.GET.get('return_Url','/home/') 16 print(return_url) 17 # 设置 session 字典属性 18 request.session['user'] = user_obj.username 19 request.session['age'] = 88 20 # 进行判断 21 if remember_7: 22 # 如果用户勾选七天免登录则设置 session 过期时间 23 request.session.set_expiry(7*24*60*60) 24 else: 25 # 如果用户没有勾选则设置 session 过期时间为0 26 request.session.set_expiry(0) 27 28 return redirect(return_url) 29 return render(request, 'login.html',{'msg':'用户名或密码错误!'}) 30 31 # 验证装饰器 32 def check_login(func): 33 @wraps(func) 34 def inner(request,*args,**kwargs): 35 # 先做 session 验证 36 session_obj = request.session.get('user',None) 37 print(session_obj) 38 if session_obj: 39 rep = func(request,*args,**kwargs) 40 return rep 41 else: 42 return_url = request.path_info 43 return redirect('/login/?return_Url={}'.format(return_url)) 44 return inner 45 46 # 删除 注销函数 47 @check_login 48 def home(request): 49 if request.method == "POST": 50 request.session.flush() # 删除当前 session 并让 cookie 失效 51 52 return redirect('/login/') 53 return render(request, 'home.html')
Django中的Session配置
1 1. 数据库Session 2 SESSION_ENGINE = 'django.contrib.sessions.backends.db' # 引擎(默认) 3 4 2. 缓存Session 5 SESSION_ENGINE = 'django.contrib.sessions.backends.cache' # 引擎 6 SESSION_CACHE_ALIAS = 'default' # 使用的缓存别名(默认内存缓存,也可以是memcache),此处别名依赖缓存的设置 7 8 3. 文件Session 9 SESSION_ENGINE = 'django.contrib.sessions.backends.file' # 引擎 10 SESSION_FILE_PATH = None # 缓存文件路径,如果为None,则使用tempfile模块获取一个临时地址tempfile.gettempdir() 11 12 4. 缓存+数据库 13 SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db' # 引擎 14 15 5. 加密Cookie Session 16 SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies' # 引擎 17 18 其他公用设置项: 19 SESSION_COOKIE_NAME = "sessionid" # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串(默认) 20 SESSION_COOKIE_PATH = "/" # Session的cookie保存的路径(默认) 21 SESSION_COOKIE_DOMAIN = None # Session的cookie保存的域名(默认) 22 SESSION_COOKIE_SECURE = False # 是否Https传输cookie(默认) 23 SESSION_COOKIE_HTTPONLY = True # 是否Session的cookie只支持http传输(默认) 24 SESSION_COOKIE_AGE = 1209600 # Session的cookie失效日期(2周)(默认) 25 SESSION_EXPIRE_AT_BROWSER_CLOSE = False # 是否关闭浏览器使得Session过期(默认) 26 SESSION_SAVE_EVERY_REQUEST = False # 是否每次请求都保存Session,默认修改之后才保存(默认)
CBV中加装饰器
要在 CBV 视图中使用 验证装饰器, 必须用 method_decorator 方法.
from django.utils.decorators import method_decorator
加在CBVget或者post方法上
from django.utils.decorators import method_decorator
class UserinfoView(views.View):
# 装饰器方法
@method_decorator(check_login)
def get(self,request):
return render(request,'userinfo.html')
def post(self,request):
request.session.flush() # 删除当前 session 并让 cookie 失效
return redirect('/login/')
加在 dispatch方法上
因为 CBV 中首先执行就是 dispatch 方法, 所以只要在 dispath 方法中加校验装饰器函数就相当于给 git/post 方法都加上了.
from django.utils.decorators import method_decorator
class UserinfoView(views.View):
@method_decorator(check_login)
def dispatch(self, request, *args, **kwargs):
return super(UserinfoView,self).dispatch(request, *args, **kwargs)
def get(self,request):
return render(request,'userinfo.html')
def post(self,request):
request.session.flush() # 删除当前 session 并让 cookie 失效
return redirect('/login/')
加在视图类上
如果 get 和 post 方法都需要登录校验的话就写两个装饰器.
@method_decorator(check_login,name='get')
@method_decorator(check_login,name='post')
class UserinfoView(views.View):
def get(self,request):
return render(request,'userinfo.html')
def post(self,request):
request.session.flush() # 删除当前 session 并让 cookie 失效
return redirect('/login/')
CSRF Token
CSRF Token 相关装饰器在 CBV 只要加上 dispath 方法,或者加载视图类上然后 name 参数指定为 dispatch方法.
- csrf_prottect: 为当前函数强制设置跨站请求伪造功能, 即便 settings 中没有设置全局中间件.
- csrf_exempt: 取消当前函数跨站请求伪造功能, 即便 settings 中设置了全局中间件.
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt,csrf_protect
@method_decorator(check_login,name='get')
@method_decorator(check_login,name='post')
class UserinfoView(views.View):
# 取消 csrf 跨站请求伪造验证功能
@method_decorator(csrf_exempt)
def dispatch(self, request, *args, **kwargs):
return super(UserinfoView,self).dispatch(request, *args, **kwargs)
def get(self,request):
return render(request,'userinfo.html')
def post(self,request):
request.session.flush() # 删除当前 session 并让 cookie 失效
return redirect('/login/')
作者:闫世成
出处:http://cnblogs.com/yanshicheng

浙公网安备 33010602011771号