python-django_session原理流程_django_中间件_CSRF-跨站请求伪造

django

1. django的session原理流程

在这里插入图片描述

2. django 中间件

1. 中间件简介

"""
django中间件是django的门户
    1.请求来的时候需要先经过中间件才能到达真正的django后端
    2.响应走的时候最后也需要经过中间件才能发送出去

django自带七个中间件
"""

# 研究django中间件代码规律
	django 中的中间件(middleware),在django中,中间件其实就是一个类,在请求到来和结束后,django会根据自己的规则在合适的时机执行中间件中相应的方法。
	在django项目的settings模块中,有一个 MIDDLEWARE_CLASSES 变量,其中每一个元素就是一个中间件
    
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

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
      
class CsrfViewMiddleware(MiddlewareMixin):
  	def process_request(self, request):
        csrf_token = self._get_token(request)
        if csrf_token is not None:
            # Use same token next time.
            request.META['CSRF_COOKIE'] = csrf_token
            
    def process_view(self, request, callback, callback_args, callback_kwargs):
        return self._accept(request)

    def process_response(self, request, response):
        return response
      
class AuthenticationMiddleware(MiddlewareMixin):
    def process_request(self, request):
        request.user = SimpleLazyObject(lambda: get_user(request))
        
"""
django支持程序员自定义中间件并且暴露给程序员五个可以自定义的方法
	1. 必须掌握
		process_request
		
		process_response
	2. 了解即可
		process_view
			
		process_template_response
		
		process_exception
"""

2. 自定义中间件

自定义步骤:
	-写一个类,继承MiddlewareMixin
    -里面写方法process_request(请求来了,一定会触发它的执行)
    -在setting中配置(注意,放在前和放在后)
    	MIDDLEWARE = [
            ...
    		'app01.mymiddle.MyMiddleware1',
            ...
		]
        
"""
1. 在项目名或者应用名下创建一个任意名称的文件夹
2. 在该文件夹内创建一个任意名称的py文件
3. 在该py文件内需要书写类(这个类必须继承MiddlewareMixin)
	然后在这个类里面就可以自定义五个方法了
	(这五个方法并不是全部都需要书写,用几个写几个)
4. 需要将类的路径以字符串的形式注册到配置文件中才能生效
    MIDDLEWARE = [
        'django.middleware.security.SecurityMiddleware',
        'django.contrib.sessions.middleware.SessionMiddleware',
        'django.middleware.common.CommonMiddleware',
        'django.middleware.csrf.CsrfViewMiddleware',
        'django.contrib.auth.middleware.AuthenticationMiddleware',
        'django.contrib.messages.middleware.MessageMiddleware',
        'django.middleware.clickjacking.XFrameOptionsMiddleware',
        '你自己写的中间件的路径1',
        '你自己写的中间件的路径2',
        '你自己写的中间件的路径3',
    ]
"""
# 中间件方法解析
1. process_request 
    1. 请求来的时候需要经过每一个中间件里面的process_request方法
       结果的顺序是按照配置文件中注册的中间件从上往下的顺序依次执行
    2. 如果中间件里面没有定义该方法,那么直接跳过执行下一个中间件
    3. 如果该方法返回了HttpResponse对象,那么请求将不再继续往后执行
       而是直接原路返回(校验失败不允许访问...)
       process_request方法就是用来做全局相关的所有限制功能
			
2. process_response
    1. 响应走的时候需要结果每一个中间件里面的process_response方法
       该方法有两个额外的参数request,response
    2. 该方法必须返回一个HttpResponse对象
    3. 默认返回的就是形参response
    4. 你也可以自己返回自己的
    5. 顺序是按照配置文件中注册了的中间件从下往上依次经过
    
3. process_view 
    路由匹配成功之后执行视图函数之前会自动执行 (callback就是视图函数)
    顺序是按照配置文件中注册的中间件从上往下的顺序依次执行
    def process_view(self, request, callback, callback_args, callback_kwargs):
        print(callback)
        print(callback_args)
        print(callback_kwargs)
        res=callback(request)
        print("中间件的process_view")
        return res
			
4. process_template_response
    返回的HttpResponse对象有render属性的时候才会触发
    顺序是按照配置文件中注册了的中间件从下往上依次经过

5. process_exception
    当视图函数中出现异常的情况下触发 (全局异常捕获)
    顺序是按照配置文件中注册了的中间件从下往上依次经过  
    应用场景: 记录日志,哪个ip地址,访问哪个路径,出现异常
    # 全局异常捕获,返回4开头的
    def process_exception(self, request, exception):
        print(exception)
        return render(request,'error.html')
 
# 注意    
	如果在第一个process_request方法就已经返回了HttpResponse对象,那么响应走的时候会直接走同级别的process_reponse返回
    
# 多个中间件的执行顺序
	请求来的时候从上往下执行: process_request
    请求走的时候从下往上执行: process_response
        
# process_request 应用场景
	写一个中间件,不管前端用什么编码,在requset.data中都有post的数据
    频率限制(限制某个ip地址,一分钟只能访问5次)
    登录认证(只要没登录,重定向到login路径)、
    记录用户访问日志(ip,时间,访问路径)
    
# process_response 应用场景 内部有response对象
	统一给所有(某几个路径)加cookie
    统一给所有(某几个路径)加响应头        

3. CSRF_TOKEN跨站请求伪造

1. 示例

# 钓鱼网站
	我搭建一个跟正规网站一模一样的界面(中国银行)
	用户不小心进入到了我们的网站,用户给某个人打钱
	打钱的操作确确实实是提交给了中国银行的系统,用户的钱也确确实实减少了
	但是唯一不同的时候打钱的账户不适用户想要打的账户变成了一个莫名其妙的账户

# 大学英语四六级
	考之前需要学生自己网站登陆缴费

# 内部本质
	我们在钓鱼网站的页面 针对对方账户 只给用户提供一个没有name属性的普通input框
	然后我们在内部隐藏一个已经写好name和value的input# 如何规避上述问题
	csrf跨站请求伪造校验
		网站在给用户返回一个具有提交数据功能页面的时候会给这个页面加一个唯一标识
		当这个页面朝后端发送post请求的时候 我的后端会先校验唯一标识
        如果唯一标识不对直接拒绝(403 forbbiden)如果成功则正常执行	

2. csrf_token校验

# django解决了csrf攻击 
	中间件:django.middleware.csrf.CsrfViewMiddleware
    用户每次发送post请求,都需要携带csrf_token随机字符串 

# form表单校验
	form表单提交 
    	在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>
        
# ajax校验
    # 方式一:放到data中 利用标签属性查找获取随机字符串
     $.ajax({
            url: '/csrf_test/',
            method: 'post',
            data: {'name': $('[name="name"]').val(),
                   'password': $('[name="password"]').val(),
                   'csrfmiddlewaretoken':$('[name="csrfmiddlewaretoken"]').val()
            },
            success: function (data) {
                console.log('成功了')
                console.log(data)

            },
            error: function (data) {
                console.log('xxxxx')
                console.log(data)
            }
        })
        
	# 方式二:放到data中 利用模版语法提供的快捷书写
		data: {"username":'jason','csrfmiddlewaretoken':'{{ csrf_token }}'},
            
	# 方式三:放到请求头中 利用模版语法提供的快捷书写
		headers: {'X-CSRFToken':'{{ csrf_token }}'},

3. 代码演示

function getCookie(name) {
    var cookieValue = null;
    if (document.cookie && document.cookie !== '') {
        var cookies = document.cookie.split(';');
        for (var i = 0; i < cookies.length; i++) {
            var cookie = jQuery.trim(cookies[i]);
            // Does this cookie string begin with the name we want?
            if (cookie.substring(0, name.length + 1) === (name + '=')) {
                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                break;
            }
        }
    }
    return cookieValue;
}
var csrftoken = getCookie('csrftoken');

function csrfSafeMethod(method) {
  // these HTTP methods do not require CSRF protection
  return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}

$.ajaxSetup({
  beforeSend: function (xhr, settings) {
    if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
      xhr.setRequestHeader("X-CSRFToken", csrftoken);
    }
  }
});

4. csrf装饰器

# 在视图函数上加装饰器
	1. 网站整体都不校验csrf 就单单几个视图函数需要校验
	   @csrf_protect  需要校验  
	2. 网站整体都校验csrf 就单单几个视图函数不校验
       @csrf_exempt   忽视校验
    
from django.views.decorators.csrf import csrf_exempt,csrf_protect
from django.utils.decorators import method_decorator

# FBV
# 全局启用,局部禁用(中间件不能注释,这个视图函数,已经没有csrf校验了)
@csrf_exempt
def csrf_test(request):
    if request.method=='GET':
        return render(request,'csrf_test.html')
    else:
        name=request.POST.get('name')
        password=request.POST.get('password')
        print(name)
        print(password)
        return HttpResponse('登录成功')

# 全局禁用,局部使用csrf
@csrf_protect
def csrf_test(request):
    if request.method=='GET':
        return render(request,'csrf_test.html')
    else:
        name=request.POST.get('name')
        password=request.POST.get('password')
        print(name)
        print(password)
        return HttpResponse('登录成功')

# 装饰器本质调用方式 在urls.py中
	path('csrf_test/', csrf_exempt(views.csrf_test))
    
# CBV
# 针对csrf_protect符合装饰器的三种玩法
@method_decorator(csrf_protect,name='post')
class MyCsrfToken(View):
    @method_decorator(csrf_protect)
    @method_decorator(csrf_exempt)   # 针对csrf_exempt只能给dispatch方法加才有效
    def dispatch(self, request, *args, **kwargs):
        return super(MyCsrfToken, self).dispatch(request,*args,**kwargs)

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

    @method_decorator(csrf_protect)
    def post(self,request):
        return HttpResponse('post')

4. 模块 importlib

# 示例一
import importlib

# 该方法最小只能到py文件名
res = 'myfile.b'
ret = importlib.import_module(res) <=> from myfile import b

# 示例二
def send_all(content):
    
    # path_str = 'notify.email.Email'
    for path_str in settings.NOTIFY_LIST:  
        
        # module_path = 'notify.email'  class_name = 'Email'
        module_path,class_name = path_str.rsplit('.',maxsplit=1)
        
        # 1. 利用字符串导入模块
        module = importlib.import_module(module_path)  # from notify import email
        # 2. 利用反射获取类名
        cls = getattr(module,class_name)  # Email、QQ、Wechat
        # 3. 生成类的对象
        obj = cls()
        # 4. 利用鸭子类型直接调用send方法
        obj.send(content)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Python Django 是一个流行的 Web 框架,可以用于快速开发高质量的 Web 应用程序。在 Django ,一个应用程序可以由多个模块组成,并且可以轻松地与其他应用程序集成。在这里,我将为您提供一些建议和指导,以帮助您开始使用 Django 构建学生管理系统。 1. 安装 Django: 首先,你需要安装 Django。你可以通过 pip 命令安装 Django,例如:`pip install django` 2. 创建一个 Django 项目: 接下来,你需要创建一个 Django 项目。你可以运行以下命令来创建一个名为 myproject 的新项目:`django-admin startproject myproject` 3. 创建一个 Django 应用程序: 接下来,你需要创建一个名为 students 的新应用程序。你可以运行以下命令:`python manage.py startapp students` 4. 配置数据库: Django 默认使用 SQLite 数据库。如果你想使用其他数据库(如 MySQL 或 PostgreSQL),你需要修改 myproject/settings.py 文件的 DATABASES 设置。 5. 创建模型: 在 Django ,模型是与数据库表对应的 Python 类。你需要在 students/models.py 文件创建一个名为 Student 的模型,包括学生的姓名、年龄和成绩。 6. 进行数据库迁移: 在创建模型后,你需要运行以下命令来将模型同步到数据库:`python manage.py makemigrations students`,然后运行 `python manage.py migrate` 命令进行数据库迁移。 7. 创建视图: 视图是 Django 应用程序处理请求和生成响应的代码。你需要在 students/views.py 文件创建一个名为 student_list 的视图,用于显示所有学生的列表。 8. 创建 URL: URL 是 Django 应用程序的网址,它将请求路由到正确的视图。你需要在 students/urls.py 文件创建一个 URL 模式,将 student_list 视图与 URL 路径关联起来。 9. 创建模板: 模板是 Django 的 HTML 文件,用于呈现视图。你需要在 students/templates/students 目录创建一个名为 student_list.html 的模板,用于显示学生列表。 10. 运行服务器: 最后,你可以运行以下命令来启动 Django 服务器:`python manage.py runserver` 这只是一个基本的概述,但它应该帮助你开始使用 Django 构建学生管理系统。如果你需要更详细的指导,请参考 Django 官方文档。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

I believe I can fly~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值