cookie与session,还有中间件

cookie与session,还有中间件

一、cookie与session

​ HTTP协议是无状态的,如果需要保存数据,也就是“保持状态”,就需要用到cookie。

​ Cookie具体指的是一段小信息,它是服务器发送出来存储在浏览器上的一组组键值对,下次访问服务器时浏览器会自动携带这些键值对,以便服务器提取有用信息。

​ cookie的工作原理是:由服务器产生内容,浏览器收到请求后保存在本地;当浏览器再次访问时,浏览器会自动带上Cookie,服务器能通过Cookie的内容来判断用户身份。

obj = HttpRespones()
# 设置cookie
obj.set_cookie(key, value,...)
# 获取
request.CKKOIES.get()
# 删除
obj.delete_cookie()
# 设置标签
obj.set_signed_cookie(key, value, salt='加盐', max_age=None,...)
# 其他属性:dafault 默认值  expires 超过时间 domain 生效域名  path 路径

​ 登录校验(cookie):

from django.shortcuts import render,HttpResponse,redirect

def login(request):
    if request.mothed == 'POST':
        username = request.POST.get('username')
        pwd = request.POST.get('pwd')
        if username == 'lalala' and pwd == '123':
            old_path = request.GET.get('next')
            if old_path:
                # 保存用户一登陆状态
                obj = redirect(old_path)
            else:
                obj = redirect('/home/')
            obj.set_cookie('name', 'lalala') #让浏览器记录一个键值对
            return obj
    return render(request, 'login.html')

1.2 session

​ cookie一定程度上解决了保持状态的需求,但是由于其容量小(4096字节),而且保存在本地客户端,致使存在安全隐患。session保存在服务端,而且容量大,可以解决cookie安全性低的问题。

​ 每个客户端的cookie被分配了唯一的id,服务端通过id识别用户身份,并将登录信息保存在session或者与已保存在session中的信息配对对比,完成身份存储和校验。

# 设置session
request.session['key'] = value  # 此时进产生一个缓存
'''
            1.django内部自动生成了随机的字符串
            2.在django_session表中存入数据
                session_key          session_data         date
                随机字符串1              数据1              ...
                随机字符串2              数据2              ...
                随机字符串3              数据3              ...
            3.将产生的随机字符串发送给浏览器 让浏览器保存到cookie中
                sessionid:随机字符串

'''
# 获取session
request.session.get('key')
'''
        1.浏览器发送cookie到django后端之后 django会自动获取到cookie值
         2.拿着随机字符串去django_session表中比对 是否有对应的数据
         3.如果比对上了 就讲随机字符串所对应的数据 取出赋值给request.session
         4.如果对不上 那么request.session就是个空
         注意:django session表是针对浏览器的,不同的浏览器来 才会有不同的记录
'''
# 删除session
request.session.delete()  # 只删除服务端的session
request.session.flush()   #浏览器和服务端的都删除
# 设置超时
request.session.set_expiry(value)
'''
        value: 数字       --->数值秒后失效
               0         --->关闭浏览器后失效
               不写       --->依赖全局session失效
               时间格式    --->时间后失效
        django session默认的过期时间是14天
'''
# 检查key是否存在
request.session.exists('session_key')
# 删除所有失效日期小与当前日期的session
request.session.clear_expired 

​ 登录校验(session):

from functools impory wraps

def check_login(func):
    @wraps(func)
    def inner(request, *args, **wkargs):
        next_url = request.get_full_path()
        if request.session.get('user'):
            return func(request, *args, **kwargs)
        else:
            return redirect('/login/?next={}'.format(next_url))
        return inner
   
def login(request):
    if request.method == 'POST':
        user = request.POST.get('user')
        pwd = request.POST.get('pwd')
        
        if user == 'lalala' and pwd == '123':
            # 设置session
            request.session['user'] = user
            # 获取到跳转到登录页面之前的url
            next_url = request.GET.get('next')
            if next_url:
                return redirect(next_url)
            else:
                return redirect('/index/')
    return render(request,'login.html')

@check_login
def logout(request):
    request.session.delete()
    return redirect('/login/')

@check_login
def index(request):
    current_user = request.session.get('user',None)
    return render(request,'index.html',{'user':current_user})
   

二、中间件

​ 中间件是一个用来处理Django的请求和响应的框架级别的钩子。它是一个轻量、低级别的插件系统,用于在全局范围内改变Django的输入和输出。每个中间件组件都负责做一些特定的功能。

img

​ django中间件共有七层,每层功能各不一样,暴露给程序员五个可以自定义的方法(五个方法都是在特定的条件下自动触发的)。

# 1.新建一个任意名的py文件,写任意名的类,固定继承:
from django.utils.deprecation import MiddlewareMixin
class M(MiddlewareMixin):
    ...
    
# 2.在配置文件中注册中间件配置,手写路径

​ 五种自定义方法:

# 1.process_request:优先于视图函数进行执行,如有多个中间件时,灰暗这MIDDLEWARE中注册顺序,从上向下依次执行。不同的中间件之间传递的request是同一个对象

# 2.process_response:落后于视图函数进行执行,按照倒叙的顺序进行。

# 3.process_view:路由匹配成功之后执行视图函数之前触发

# 4.process_exception:当视图函数出现异常(bug)的时候自动触发
# 5.process_template_response:当视图函数执行完毕之后并且返回的对象中含有render方法的情况下才会触发

三、跨站请求伪造

​ 跨站请求伪造(Cross-site request forgery),也被称为 one-click attack 或session riding,通常缩写为 CSRF*或者 XSRF, 是一种挟制用户在当前已登录的Web应用程序上执行非本意的操作的攻击方法。

​ 例如银行汇款,填写的form表单中,用户名密码都是真实提交给银行后台的,但是收款人的账户虽然填写的是被转账对象的,但是实际填写的是一个没有name属性的input框,实际转账的用户是提前写好的隐藏的带有name和value的input框。

​ 解决方法:用户进入提交post请求的页面就返回一个随机的字符串,当用户提交请求时,会先自动校验这个字符串,正确就可以正常提交,匹配不正确就报403。

​ form表单:

<body>
    <h1>真正的网站</h1>
    <form action="" method="post">
        { % csrf_token % }   # 加这条代码就可以
        <p>username:<input type="text" name="username"></p>
        <p>target_user:<input type="text" name="target_user"></p>
        <p>money:<input type="text" name="money"></p>
        <input type="submit">
    </form>
</body>

​ ajax:

<body>
    { % csrf_token % }
    <script>
        %('#b1').click(function()){
            $.ajax({
                url:"",
                type:"post",
                data:{'username':'lalala'},
                success:function(data){
                    alter(data)
                }
             })
        }
    </script>
</body>
# 方法一:data:{'username':'jason','csrfmiddlewaretoken':$('[name="csrfmiddlewaretoken"]').val()},

# 方法二:data:{'username':'jason','csrfmiddlewaretoken':'{{ csrf_token }}'},

​ 方法一与方法二都是通过{% csrf_token %}获取到随机字符串,再利用标签查找。

​ 方法三,导入一个相应功能的js文件。

四、CBV视图中使用装饰器

​ 1.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')

猜你喜欢

转载自www.cnblogs.com/tangceng/p/11768053.html