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')



猜你喜欢

转载自www.cnblogs.com/kangwy/p/11768485.html