zoukankan      html  css  js  c++  java
  • cookie与session,Django中间件,跨站请求伪造

    cookie与session,Django中间件,跨站请求伪造

    一.cookie与session

    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

    rep = HttpResponse(...)
    rep = render(request, ...)
    
    rep.set_cookie(key,value,...)
    rep.set_signed_cookie(key,value,salt='加密盐', max_age=None,...)
    

    参数:

    • key: 键
    • value: 值
    • max_age=None: 超时时间

    删除Cookie

    def logout(request):
    	rep = redirect("/login/")
    	rep.delete_cookie("user") #删除用户浏览器上之前设置的usercookie值
    	return rep
    

    Cookie实现登录认证

    def login(request):
        if request.method == 'POST':
            username = request.POST.get('username')
            password = request.POST.get('password')
            if username == 'kang' and password == '123':
                old_path = request.GET.get('next')  # 拿到要访问的页面
                if old_path:
                    obj = redirect(old_path)   #如果有就返回那个页面
                else:
                    obj = redirect('/home/')
                obj.set_cookie('name','kang')  # 让客户端浏览器记录一个键值对
                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'):  #判断有没有cookie,有的话直接返回
                res = func(request,*args, **kwargs)
                return res
            else:
                target_url = request.path_info # 没有的跳转到登录页,并且附带上想要访问的
                return redirect('/login/?next=%s'%target_url)
        return inner
    
    
    @login_auth
    def home(request):
        return HttpResponse('我是主页面,登录后查看')
    
    @login_auth
    def index(request):
        return HttpResponse('我是买东西页面')
    
    @login_auth
    def play(request):
        return HttpResponse('我是玩游戏页面')
    
    @login_auth
    def logout(request):
        obj = redirect('/login/')
        obj.delete_cookie('name')
        return obj
    

    Session

    Session的由来

    1. Cookie虽然能够帮助我们解决需求,但是他本身最大支持4096字节,因为他是存在客户端的,所以也有可能被拦截或者窃取.因此出现了Session,它是存放在服务器端,并且有较高的安全性.
    2. 基于HTTP协议的无状态特征,服务器根本就不知道访问者,那么Cookie就起到了桥接的作用.
    3. 我们可以给没个客服端的Cookie分配一个唯一的id,这样在访问时,通过Cookie,服务器就知道来的人是'谁',然后在根据不同的Cookie的id,在服务器上保存一段时间的信息.如"账号密码".
    4. Cookie弥补了HTTP无状态的不足,让服务器知道了来的人是谁,但是Cookie是以文本的形式保存在本地.自身安全性较差,所以我们就通过Cookie识别不同的用户,对应的在Session保存私密的信息以及超过4096的字节文本.
    5. 所有说,Cookie和Session是共通性的东西.

    Django中的Session相关方法

    # 设置,获取,删除session中的数据
    
    #设置
    request.session['username'] = 'kang'
    
    #获取
    request.session.get('username')
    
    #删除
    request.session.flush()
    
    #设置会话Session和Cookie的超时时间
    request.session.set_expiry(value)
      如果value是个整数,session会在这些秒数后失效
      如果value是0,用户关闭浏览器就会失效.
    

    Session实现登录认证

    
    

    Django中间件

    中间件的作用

    • 用户访问频率限制
    • 用户是否是黑名单,白名单
    • 所有用户登录校验
    • 只要是涉及到网址全局的功能,你就应该考虑使用中间件.

    django中间件暴露给程序员的五个可以自定义的方法(五个方法都是在特定的条件下自定触发的)

    1.你要新建一个文件夹, 里面可以建立任意名称的py文件
    里面写类固定继承
    from django.utils.deprecation import MiddlewareMixin
    class MyThink(MiddlewareMixin):
    #五个方法:
    需要掌握的:
    1. process_request(******):请求来的时候 会从上往下依次经过每一个中间件里面process_request,一旦里面返回了HttpResponse对象那么就不再往后执行了,会执行同一级别的process_response
                 def process_request(self,request):
                     print('我是第一个自定义中间件里面的process_request方法')
                     return HttpResponse("我是第一个自定义中间件里面的HttpResponse对象返回值")  # 直接原地返回
    2.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方法的情况下才会触发
             
    

    跨站请求伪造(钓鱼网站)

    就相当于你搭建了一个和充Q币一模一样的网站,用户在你的网站进行充值的时候输入的是自己的结果充给了你.

    简单的原理

    • 在你写form表单的时候,用户的用户名,密码都会真实的提交给Q币后台
    • 但是被充的人的账户却不是用户填的,你暴露给用户的是一个没有name属性的input框
    • 你自己写好了一个隐藏的带有的name和value的input框

    解决钓鱼网站的策略

    • 只要是用户想要提交post请求的页面,我在返回给用户的时候就提前设置好一个随机字符串
    • 当用户提交post请求的时候,我会自动先获取查找是否有该随机的字符串.
    • 如果有正常提交,否则直接报403

    form表单

    你在写form表单的时候只需要加上
      {% csrf_token %} 
    

    ajax

    第一种: 自己在页面上先通过{% cstf_token %}获取到随机字符串,然后利用标签查找
    data: {'username':'kang','csrfmiddlewaretoke:$([name="csrfmiddlewaretoken"]').val()}
    
    第二种:
    data:{'username':'kang', 'csrfmiddlewaretoken':'{{ csrf_token }}'}
    
    第三种
    拷贝js文件
    
    

    如何不校验使用装饰器

    from django.views.decorators.csrf import csrf_exempt, csrf_protect
    from django.utils.decorators import method_decorator # 它作用于CBV
    
    @csrf_exempt  # 避免校验
    def exem(request):
        return HttpResponse('exempt')
    
    @csrf_protect  # 可单独校验
    def pro(request):
        return HttpResponse('pro')
    
    
    
    CBV
    from django.views import View
    # 第一种
    # @method_decorator(csrf_exempt,name='dispatch')
    @method_decorator(csrf_protect,name='post')
    class MyCsrf(View):
        # 第二种
        # @method_decorator(csrf_exempt)
        @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')
    
    
    
    
    
  • 相关阅读:
    [测试题]钦点
    香港记者
    【模板】三维偏序
    C. Journey
    B. Game of the Rows
    A. Arya and Bran
    D. Statistics of Recompressing Videos
    人们对Python在企业级开发中的10大误解
    各种开源协议介绍 BSD、Apache Licence、GPL V2 、GPL V3 、LGPL、MIT
    WPF.UIShell UIFramework之自定义窗口的深度技术
  • 原文地址:https://www.cnblogs.com/kangwy/p/11768485.html
Copyright © 2011-2022 走看看