django

1. cookie与session

# 为什么会有cookie和session?
	# 由于http协议是无状态的 无法记住用户是谁
    
# django必会三板斧
	return HttpResponse()
    return render()
	return redirect()

# 变形:
	obj1 = HttpResponse()
	return obj1
	obj2 = render()
	return obj2
	obj3 = redirect()
	return obj3
'''
cookie是保存在客户端浏览器上的键值对

是服务端设置在客户端浏览器上的键值对
也就意味着浏览器其实可以拒绝服务端的"命令"
默认情况下 浏览器都是直接让服务端设置键值对

设置cookie
	obj.set_cookie()
获取cookie
	request.COOKIES.get()
删除cookie
	obj.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 == 'yss' and password == '123':
            old_path = request.GET.get('next')    # 获取用户想要访问的地址
            if old_path:   # 如果有值,就去用户要访问的地址
                # 保存用户登录状态
                obj = redirect(old_path)
            else:   # 如果没有值,就去主页
                obj = redirect('/home/')
            obj.set_cookie('name','yss')  # 让客户端浏览器 记录一个键值对
            # obj.set_cookie('name','jason',max_age=5)  # max_age=5:后台控制过期时间 5s
            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'):   # 如果获取到name,表示已登录
            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):
    # 校验用户是否登录
    # if request.COOKIES.get('name'):
    #     return HttpResponse('我是主页 只有登录了才能看')
    # return redirect('/login/')
    return HttpResponse('我是主页 只有登录了才能看')

@login_auth
def index(request):
    return HttpResponse('我是index页面 也需要用户登录之后才能看')

@login_auth
def xxx(request):
    return HttpResponse('xxx页面 也是需要登录了之后才能看')

@login_auth
def logout(request):
    obj = redirect('/login/')
    obj.delete_cookie('name')    # 删除cookie
    return obj

1.2 session

'''
session是保存在服务器上的键值对

django中的session表是针对浏览器的
不同的浏览器来 才会有不同的记录

django session默认的过期时间是14天
'''
            
# 设置session: 
	request.session['key'] = value   # 仅仅只会在内存产生一个缓存
	'''
	1.django内部自动生成了随机的字符串
	2.在django_session表中存入数据
	3.将产生的随机字符串发送给浏览器 让浏览器保存到cookie中
		sessionid:随机字符串
	'''

# 获取session: 
	request.session.get('key')
	'''
	1.浏览器发送cookie到django后端之后 django会自动获取到cookie值
    2.拿着随机字符串去django_session表中比对 是否有对应的数据
    3.如果比对上了 就将随机字符串所对应的数据取出赋值给request.session,如果对不上 那么request.session就是空
	'''
    
# 删除session: 
	request.session.delete()   # 只删除服务端的session
	request.session.flush()    # 浏览器和服务端全部删除

# session设置超时时间:
	request.session.set_expiry(value多种配置)
'''
数字    秒
0 
不写    14天
时间格式
'''
# 设置session
def set_session(request):
    request.session['username'] = 'egondsb'
    request.session.set_expiry(value=0)
    # request.session['password'] = '123'
    # request.session['age'] = '18'
    return HttpResponse("设置session")

# 获取session
def get_session(request):
    print(request.session.get('username'))
    # print(request.session.get('password'))
    # print(request.session.get('age'))
    return HttpResponse('获取session')

# 删除session
def delete_session(request):
    # request.session.delete()   # 只删除服务端的session
    request.session.flush()   # 浏览器和服务端全部删除
    return HttpResponse("删除session")

2. 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方法的情况下才会触发
		def yyy(request):
            print('yyy视图函数')
            obj = HttpResponse('奇葩')
            def render():
                return HttpResponse('hahaha')
            obj.render = render
            return obj

3. 跨站请求伪造(csrf)

'''
跨站请求伪造(csrf)      钓鱼网站
	就类似于你搭建了一个跟银行一模一样的web页面
	用户在你的网站转账的时候输入用户名 密码 对方账户
	银行里面的钱确实少了 但是发现收款人变了
	
	
	最简单的原理
		你写的form表单中 用户的用户名  密码都会真实的提交给银行后台
		但是收款人的账户却不是用户填的 你暴露给用户的是一个没有name属性的input框
		你自己提前写好了一个隐藏的带有name和value的input框
		
		
解决钓鱼网站的策略
	只要是用户想要提交post请求的页面 我在返回给用户的时候就提前设置好一个随机字符串
	当用户提交post请求的时候  我会自动先取查找是否有该随机字符串 
	如果有 正常提交
	如果没有  直接报403 
'''

3.1 form表单

<!--你在写的时候只需要加上一个 {% csrf_token %}-->

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

3.2 ajax

<!--第一种方式-->
{% 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>
<button id="b1">发ajax</button>

<script>
    $('#b1').click(function () {
        $.ajax({
            url:"",
            type:"post",
            // 第一种方式
            data:{'username':'jason','csrfmiddlewaretoken':$('[name="csrfmiddlewaretoken"]').val()},
            success:function (data) {
                alert(data)
            }
        })
    })
</script>


<!--第二种方式-->
<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>
<button id="b1">发ajax</button>

<script>
    $('#b1').click(function () {
        $.ajax({
            url:"",
            type:"post",
            // 第二种方式
            data:{'username':'jason','csrfmiddlewaretoken':'{{ csrf_token }}'},
            success:function (data) {
                alert(data)
            }
        })
    })
</script>


<!--第三种方式-->
{% 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>
<button id="b1">发ajax</button>

<script src="/static/setup.js"></script>
<script>
    $('#b1').click(function () {
        $.ajax({
            url:"",
            type:"post",
            // 第三种方式
            data:{'username':'jason'},
            success:function (data) {
                alert(data)
            }
        })
    })
</script>

3.3 CBV中加装饰器相关

from django.views.decorators.csrf import csrf_exempt, csrf_protect
from django.utils.decorators import method_decorator

@csrf_exempt     # settings中设置了全局中间件,取消当前函数防跨站请求伪造功能
def exem(request):
    return HttpResponse('exempt')

@csrf_protect    # settings中没有设置全局中间件,为当前函数强制设置防跨站请求伪造功能
def pro(request):
    return HttpResponse('pro')


from django.views import View
# csrf_exempt只有两种装饰的方式
# 第一种:直接加在视图类上,但method_decorator必须传 name 关键字参数
# @method_decorator(csrf_exempt,name='dispatch')
class MyCsrf(View):
    # 第二种:加在dispatch方法上,因为CBV中首先执行的就是dispatch方法,所以相当于给get和post方法都加上了校验
    @method_decorator(csrf_exempt)
    def dispatch(self, request, *args, **kwargs):
        return super().dispatch(request, *args, **kwargs)

    def get(self, request):
        return HttpResponse('hahaha')

    def post(self, request):
        return HttpResponse('post')


# 除了csrf_exempt之外,所有的其他装饰器,在CBV上面都有三种方式
# 第一种:直接加在视图类上
@method_decorator(csrf_protect, name='post')
class MyCsrf(View):
    # 第二种:加在dispatch方法上
    @method_decorator(csrf_protect)
    def dispatch(self, request, *args, **kwargs):
        return super().dispatch(request, *args, **kwargs)

    def get(self, request):
        return HttpResponse('hahaha')

    # 第三种:加在post方法上
    @method_decorator(csrf_protect)
    def post(self, request):
        return HttpResponse('post')
posted @ 2019-10-30 21:35  PLPLPL  阅读(180)  评论(0编辑  收藏  举报
// 目录