Django操作session和中间件以及csrf跨站服务

发布时间 2023-05-07 19:47:35作者: 橘子熊何妨

Django操作session

# cookie保存在浏览器,数据不安全
session可以将用户信息保存在服务端,基于cookie工作的
1. 用户信息认证
2. 生成随机字符串
3. 随机字符串和用户信息绑定一起,保存,默认在mysql
4. 把随机字符串返回到浏览器,将其保存,再次访问直接带其一起传输至服务端,服务端用其进行查询,存在则已经登录过

# 在Django中默认使用session,则必须有Django——session表
在cookie中session保存的key默认是sessionid
默认的过期时间是14天

def set_session(request):  # 设置session
    # 当django设置多个值的时候,Django_session表中也只会有一条数据(一台计算机一个浏览器,只会有一条记录)
    """
        1. 生成一个随机字符串
        2. 默认保存到Django_session表中
            2.1 在中间件中操作的
            2.2 请求来的时候,把数据保存在缓存中
            2.3 响应走的时候,才执行了create方法
        3. 把随机字符串返回给浏览器
    :param request:
    :return:
    """
    request.session['username'] = 'lisi'
    return HttpResponse('session')

def get_session(request):  # 获取session
    """
        1. 获取名为session的cookie值
        2. 拿着这个cookie去数据库查询
        3. 查询到后,把这个数据封装到request.session中
    :param request:
    :return:
    """
    print(request.session.get('username'))
    print(request.session['username'])
    return HttpResponse('get_session')

def sel_session(request):  # 删除session
    request.session.delete()  # 只删数据库
    request.session.flush()  # 数据库和cookie都删除
    return HttpResponse('del_session')

# cookie和session的又一个区别:
1. cookie设置数据有大小限制
2. session理论上没有

CBV中加装饰器

from django.views import View
from django.utils.decorators import method_decorator

@method_decorator(login_auth, name='get')  # 也可以加在类上面但是要加一个name指明给哪个方法加装饰器
class Login(View):
    @method_decorator(login_auth)  # 重写dispatch,并加上装饰器,可以给所有的方法加装饰器
    def dispatch(self, request, *args, **kwargs):
        return super(Login, self).dispatch(request, *args, **kwargs)
    
    @method_decorator(login_auth)  # CBV中加装饰器
    def get(self, request):
        return HttpResponse('get')

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

Django的中间件

# django的请求声明周期流程图
1. 请求来了先经过中间件
2. 响应走了最后,也要经过中间件

# django自带的有七个中间件
在配置文件下的MIDDLEWARE这个里面的7个中间件

django的中间件给我们暴露了一些方法
class SessionMiddleware(MiddlewareMixin):
     def process_request(self, request):
            session_key = request.COOKIES.get(settings.SESSION_COOKIE_NAME)
            request.session = self.SessionStore(session_key)

     def process_response(self, request, response):
        return response
    
# 它提供了几个方法
1. 需要我们掌握的有:
	process_request
    process_response
2. 了解的方法:
	process_view----------------》是跟视图函数相关的
    process_exception----------------》跟异常相关的
    process_template_response----------------》跟模板相关的
    
# 在一个中间件中,暴露的这几个方法不是每个类都必须有的,而是需要什么就写什么

自定义中间件

# django除了默认提供了7个中间件,还支持自己定义中间件

自定义中间件的步骤:
1. 在项目名下或者应用名下新建一个任意名称的文件夹
2. 在这个文件夹下面新建一个py文件
3. 在这个py文件中,新建一个类,必须继承MiddlewareMixin
4. 在你新建的这个类下面写哪几个方法:
	process_request
    process_response
5. 一定要在配置文件的中间件里面注册你的中间件路径

# 针对process_reqeust
	1. 执行顺序是按照配置文件中注册的顺序,从上往下依次执行
    2. 视图函数在中间件的process_request函数之后执行
    3. 如果在process_request里面直接返回HttpResponse,之后的中间件一律不在走了,包括视图函数
# # 针对process_response
 	1. 必须要返回一个HttpResponse
    2. 执行顺序:是按照配置文件的注册顺序,从下往上依次执行

# 最后一个问题:
研究我在第一个中间件的process_reqeust方法中,直接返回HttpResponse,然后,观察所有中间件的process_response的执行顺序?
# 结论:如果在第一个中间件中得process_reqeust中直接拦截,只走第一个中间件的process_reqeust和第一个中间件的process_response,直接原路返回.

# 但是,在flask框架中,如果你在第一个拦截了,后面的类似于是process_response都会走一遍.
'''flask框架中实际上没有真正的中间件,它是需要你看源码自己做成类似于django的这种中间件'''

csrf跨站请求伪造

# 背景信息
钓鱼网站
“钓鱼网站”的页面与真实网站界面基本一致,欺骗消费者或者窃取访问者提交的账号和密码信息
eg:
	现在有一个正规的中国银行的网站,我自己也写一个页面根中国银行的页面完全一模一样
    有个客户去中国银行转行,不小心来到了我的这个钓鱼网站,开始在这个钓鱼网站转账,转账完毕之后,钱也少了,这个也达到了中国银行,但是,它想转账的这个对方账户不是它自己想要的哪个账户.
    
# 针对上述情况,它是怎么做到的
# 内部本质
在钓鱼网站上的form表单中,它是写一个没有name属性的input框,它在这个input框下面,在隐藏一个input框,这个隐藏的input框,我给他提前写好name属性和value值,但是用户不知道

# 如何规避上述问题?
在正规网站中给form表单一个唯一标识,然后,表单每次提交的时候,后端都做一个验证没如果正确就可以提交,如果不正确,就直接403(forbidden)


# 来研究ajax如何规避csrf的验证?
  $('.btn').click(function () {
        $.ajax({
            url: '',
            type: 'post',
            // 方式1:
            {#data: {'username': 'kevin', 'csrfmiddlewaretoken': $("[name='csrfmiddlewaretoken']").val()},#}
            // 方式2
            {#data: {'username': 'kevin', 'csrfmiddlewaretoken': '{{ csrf_token }}'},#}
            data: {'username': 'kevin'},
            // 方式3,使用js
            success: function (res) {

            }
        })
    })