Django源码分析-中间件层源码解读(六)

1.中间件加载过程源码分析

1.请求到达:请求首先通过 Django 的 Handler 处理器,具体是在 django.core.handlers.base.BaseHandler 类中的 get_response 方法开始处理。
2.中间件处理链创建: 在 get_response 方法中,Django 通过self.load_middleware()函数构建了一个中间件处理链。load_middleware 方法会遍历项目的中间件设置(在 settings.py 中配置),并按顺序加载中间件。
3.中间件处理链执行: 在 get_response 方法中,当请求到达时,Django 会遍历中间件处理链,依次调用每个中间件的 process_request 方法。
4.视图处理: 请求经过中间件的 process_request 处理后,进入视图处理阶段。视图是在 django.core.handlers.base.BaseHandler 类的 get_response 方法中调用的。
5.中间件处理链执行(响应阶段): 在视图函数执行后,Django 再次遍历中间件处理链,调用每个中间件的 process_response 方法。

# django/core/handlers/base.py

class BaseHandler:
    def __init__(self):
        self._request_middleware = self.load_middleware('request')
        self._response_middleware = self.load_middleware('response')

    def load_middleware(self, phase):
        middleware_list = []
        # 获取 settings.py 中配置的中间件路径列表
        middleware_paths = settings.MIDDLEWARE
        for middleware_path in middleware_paths:
            middleware = import_string(middleware_path)
            if hasattr(middleware, f'process_{phase}'):
                middleware_list.append(middleware)
        return middleware_list

    def get_response(self, request):
        # 请求到达时执行请求阶段中间件
        for middleware in self._request_middleware:
            response = middleware.process_request(request)
            # ...

        # 视图处理
        response = wrapped_callback(request, *callback_args, **callback_kwargs)

        # 视图处理后执行响应阶段中间件
        for middleware in self._response_middleware:
            response = middleware.process_response(request, response)
            # ...

        return response

2.crsf_token生成和校验源码详解

在 Django 中,CSRF(Cross-Site Request Forgery)防护是通过生成和验证 CSRF 令牌(CSRF Token)来实现的。

  • CSRF 令牌生成
    CSRF 令牌生成是在 Django 的 django.middleware.csrf.CsrfViewMiddleware 中间件中完成的。具体的源码位于 django.middleware.csrf 模块中的 CsrfViewMiddleware 类。

    class CsrfViewMiddleware(MiddlewareMixin):
        def process_view(self, request, callback, callback_args, callback_kwargs):
            # ...
    
            # 生成 CSRF 令牌
        csrf_token = self._get_token(request)
    
        # 将生成的令牌添加到请求的上下文中
        request.csrf_token = csrf_token
    
        def _get_token(self, request):
            # 生成 CSRF 令牌
            return get_token(request)
     
    def get_token(request):
       if "CSRF_COOKIE" not in request.META:
            # 如果没有 CSRF Cookie,生成一个新的 CSRF 令牌
            request.META["CSRF_COOKIE"] = _get_new_csrf_key()
        return request.META["CSRF_COOKIE"]
    
    # 使用了一定的随机性,结合时间戳、随机数、和字符串生成了一个新的 CSRF 令牌。
    def _get_new_csrf_key():
        return _salt() + md5(("%s%s" % (randrange(0, _MAX_CSRF_KEY), get_random_string())).encode()).hexdigest()
    
  • CSRF 令牌校验
    CSRF 令牌的校验是在 Django 的 django.middleware.csrf.CsrfViewMiddleware 中间件中的 process_view 方法中完成的。

    class CsrfViewMiddleware(MiddlewareMixin):
        def process_view(self, request, callback, callback_args, callback_kwargs):
            # ...
    
            # 校验 CSRF 令牌
            self._enforce_csrf(request, response)
    
        def _enforce_csrf(self, request, response):
            # 校验 CSRF 令牌
            csrf_token = request.POST.get('csrfmiddlewaretoken') or request.GET.get('csrfmiddlewaretoken')
    
            if csrf_token != request.csrf_token:
                # CSRF 令牌校验失败,触发异常
                raise CsrfViewMiddleware._get_failure_view()(request, reason='CSRF token missing or incorrect.')
    
    
  • 21
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值