cookie与session
#为什么会有cookie和session?
由于http协议是无状态的 无法记住用户是谁
cookie
cookie是服务端设置并保存在客户端浏览器上的键值对
也就意味着浏览器其实可以拒绝服务端的"命令"
默认情况下 浏览器都是直接让服务端设置键值对
#使用cookies需要对三板斧变形
return HttpResponse()
return render()
return redirect()
变形:
obj1 = HttpResponse()
return obj1
obj2 = render()
return obj2
obj3 = redirect()
return obj3
#cookies操作
设置
obj1.set_cookie()
获取
request.COOKIES.get()
删除
obj1.delete_cookie()
#登陆功能
def login(request):
# print(request.path_info) # 只拿url 不拿get请求携带的额参数
# print(request.get_full_path()) # 都拿
if request.method == "POST":
username = request.POST.get('username')
password = request.POST.get('password')
if username == 'jason' and password == '123':
old_path = request.GET.get('next')
if old_path:
# 保存用户登录状态
obj = redirect(old_path)
else:
obj = redirect('/home/')
obj.set_cookie('name','jason') # 让客户端浏览器 记录一个键值对
# obj.set_cookie('name','jason',max_age=5) # 存在时间
return obj
return render(request,'login.html')
from functools import wraps
def login_auth(func):
@wraps(func)
def inner(request,*args,**kwargs):
if request.COOKIES.get('name'):
res = func(request,*args,**kwargs)
return res
else:
target_url = request.path_info
return redirect('/login/?next=%s'%target_url)
return inner
session
session是保存在服务器上的键值对
django session默认的过期时间是14天
#操作session
设置
request.session['key'] = value # 仅仅只会在内存产生一个缓存,在经过中间件时才会存储,需要运行一下数据库迁移,django自动创建一张session表
1.django内部自动生成了随机的字符串
2.在django_session表中存入数据
session_key |session_data |date
随机字符串1 数据1 ...
随机字符串2 数据2 ...
随机字符串3 数据3 ...
3.将产生的随机字符串发送给浏览器 以键值对的形式让浏览器保存到cookie中
{sessionid:随机字符串}
获取
request.session.get('key')
1.浏览器发送cookie到django后端之后 django会自动获取到cookie值
2.拿着随机字符串去django_session表中比对 是否有对应的数据
3.如果比对上了 就讲随机字符串所对应的数据 取出赋值给request.session
如果对不上 那么request.session就是个空
注意:django session表是针对浏览器的不同的浏览器来 才会有不同的记录
删除
request.session.delete() # 只删除服务端的session
request.session.flush() # 浏览器和服务端全部删除
session也可以设置超时时间
request.session.set_expiry(value多种配置)
django中间件(******)
#功能:
用户访问频率限制
用户是否是黑名单 白名单
所有用户登录校验
只要是涉及到网址全局的功能 你就应该考虑使用中间件
#使用方式
django中间件暴露给程序员五个可以自定义的方法(五个方法都是在特定的条件下自动触发的)
1.新建一个文件夹 里面新建一个任意名称的py文件
里面写类 固定继承
from django.utils.deprecation import MiddlewareMixin
class MyMiddle(MiddlewareMixin):
...
2.去配置文件注册到中间件配置中
你需要手写字符串的路径
'app01.mymiddleware.myaabb.MyMiddle1'
#需要掌握的
process_request(******):请求来的时候 会从上往下依次经过每一个中间件里面process_request,一旦里面返回了HttpResponse对象那么就不再往后执行了 会执行同一中间件内的process_response
def process_request(self,request):
print('我是第一个自定义中间件里面的process_request方法')
return HttpResponse("我是第一个自定义中间件里面的HttpResponse对象返回值") # 直接原地返回
process_response(***):响应走的时候 会从下往上依次进过每一个中间件里面的process_response
def process_response(self,request,response): # response就是要返回给用户的数据
print("我是第一个自定义中间件里面的process_response方法")
return response
#了解的
process_view:路由匹配成功之后执行视图函数之前触发
process_exception:当视图函数出现异常(bug)的时候自动触发
process_template_response:当视图函数执行完毕之后并且返回的对象中含有render方法的情况下才会触发
跨站请求伪造(csrf) 钓鱼网站
就类似于你搭建了一个跟银行一模一样的web页面
用户在你的网站转账的时候输入用户名 密码 对方账户
银行里面的钱确实少了 但是发现收款人变了
#最简单的原理
你写的form表单中 用户的用户名 密码都会真实的提交给银行后台
但是收款人的账户却不是用户填的 你暴露给用户的是一个没有name属性的input框
你自己提前写好了一个隐藏的带有name和value的input框
#解决钓鱼网站的策略
只要是用户想要提交post请求的页面 我在返回给用户的时候就提前设置好一个随机字符串
当用户提交post请求的时候 我会自动先取查找是否有该随机字符串
如果有 正常提交
如果没有 直接报403
form表单
你在写的时候只需要加上一个
{% csrf_token %}
ajax
第一种 自己再页面上先通过{% csrf_token %}获取到随机字符串 然后利用标签查找
data:{'username':'jason','csrfmiddlewaretoken':$('[name="csrfmiddlewaretoken"]').val()},
第二种
data:{'username':'jason','csrfmiddlewaretoken':'{{ csrf_token }}'},
第三种
拷贝相关的js文件
#针对某个函数是否需要或者免于csrf中间件校验的装饰器
FBV
from django.views.decorators.csrf import csrf_exempt, csrf_protect
@csrf_exempt #免除校验
def exem(request):
return HttpResponse('exempt')
@csrf_protect #需要校验
def pro(request):
return HttpResponse('pro')
CBV
#csrf_exempt 只有两种装饰的方式
from django.views.decorators.csrf import csrf_exempt, csrf_protect
from django.utils.decorators import method_decorator
# 第一种
#@method_decorator(csrf_exempt,name='dispatch')
class MyCsrf(View):
# 第二种
@method_decorator(csrf_exempt)
def dispatch(self, request, *args, **kwargs):
return super().dispatch(request,*args,**kwargs)
def get(self,request):
return HttpResponse('hahaha')
注意:除了csrf_exempt之外 所有的其他装饰器 在CBV上面都有三种方式
@method_decorator(csrf_protect,name='post')
class MyCsrf(View):
@method_decorator(csrf_protect)
def dispatch(self, request, *args, **kwargs):
return super().dispatch(request,*args,**kwargs)
def get(self,request):
return HttpResponse('hahaha')
@method_decorator(csrf_protect)
def post(self,request):
return HttpResponse('post')