CBV 基本使用

视图函数的本质是接收一个httprequest 对象,返回httpresponse 对象,fbv就是这么一个函数,cbv的as_view() 也是返回这么一个函数。

  1. from django.shortcuts import render,HttpResponse
  2. from django.views import View
  3. class Login(View):
  4. def get(self,request):
  5. return HttpResponse("GET 方法")
  6. def post(self,request):
  7. user = request.POST.get("user")
  8. pwd = request.POST.get("pwd")
  9. if user == "runoob" and pwd == "123456":
  10. return HttpResponse("POST 方法")
  11. else:
  12. return HttpResponse("POST 方法 1")

利用反射,get请求对应 类里的get 方法,post请求对应post 方法

  1. def dispatch(self, request, *args, **kwargs):
  2. # Try to dispatch to the right method; if a method doesn't exist,
  3. # defer to the error handler. Also defer to the error handler if the
  4. # request method isn't on the approved list.
  5. if request.method.lower() in self.http_method_names:
  6. # 关键反射
  7. handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
  8. else:
  9. handler = self.http_method_not_allowed
  10. return handler(request, *args, **kwargs)

流程:
url方法 -> view方法 -> dispath方法 (反射方法 get/post/delete/put )

CSRF原理

从使用反推。
模板中如何添加 csrfmiddlewaretoken
cookie 中如何设置 csrftoken
两个值在什么时候验证是否一致

  1. 模板文件添加 {% csrf_token %}

这部分代码在 django.template.defaulttags

  1. def csrf(request):
  2. """
  3. Context processor that provides a CSRF token, or the string 'NOTPROVIDED' if
  4. it has not been provided by either a view decorator or the middleware
  5. """
  6. def _get_val():
  7. # 调用 中间件 csrf 里的 get_token()
  8. token = get_token(request)
  9. if token is None:
  10. # In order to be able to provide debugging info in the
  11. # case of misconfiguration, we use a sentinel value
  12. # instead of returning an empty dict.
  13. return 'NOTPROVIDED'
  14. else:
  15. return token
  16. return {'csrf_token': SimpleLazyObject(_get_val)}
  1. 调用中间件的csrf 里的 get_token()

    1. def get_token(request):
    2. if "CSRF_COOKIE" not in request.META:
    3. csrf_secret = _get_new_csrf_string()
    4. request.META["CSRF_COOKIE"] = _salt_cipher_secret(csrf_secret)
    5. else:
    6. csrf_secret = _unsalt_cipher_token(request.META["CSRF_COOKIE"])
    7. # 关键,通过设置 CSRF_COOKIE_USED 这个值为True
    8. request.META["CSRF_COOKIE_USED"] = True
    9. return _salt_cipher_secret(csrf_secret)
  2. 在 csrf 中间件里的 process_response 里,设置 cookie 里的 csrftoken

    1. def process_response(self, request, response):
    2. if not getattr(request, 'csrf_cookie_needs_reset', False):
    3. if getattr(response, 'csrf_cookie_set', False):
    4. return response
    5. # 上面设置了 这边值为True
    6. if not request.META.get("CSRF_COOKIE_USED", False):
    7. return response
    8. if settings.CSRF_USE_SESSIONS:
    9. if request.session.get(CSRF_SESSION_KEY) != request.META['CSRF_COOKIE']:
    10. request.session[CSRF_SESSION_KEY] = request.META['CSRF_COOKIE']
    11. else:
    12. response.set_cookie(
    13. settings.CSRF_COOKIE_NAME,
    14. request.META['CSRF_COOKIE'],
    15. max_age=settings.CSRF_COOKIE_AGE,
    16. domain=settings.CSRF_COOKIE_DOMAIN,
    17. path=settings.CSRF_COOKIE_PATH,
    18. secure=settings.CSRF_COOKIE_SECURE,
    19. httponly=settings.CSRF_COOKIE_HTTPONLY,
    20. samesite=settings.CSRF_COOKIE_SAMESITE,
    21. )
    22. # Set the Vary header since content varies with the CSRF cookie.
    23. patch_vary_headers(response, ('Cookie',))
    24. response.csrf_cookie_set = True
    25. return response
  3. 在 process_view 里验证 csrf 是否一致 ```python

    页面 {% csrf_token %} 设置的

    csrfmiddlewaretoken = “dGZNEIV1rwUbMJA4EDRHaJGHHydZLVEFv9NlvurLtj30vzr8rVuwh71Pe0miHEDf”

    cookie 里取的

    csrf_token = “8JDrBEx0K2ia0KFGaYGCg9mYmzYANFMtqcrZsq3KMPrZJAwKXgjrnxH6T17TJoL3”

    比较两边一致

print(_compare_salted_tokens(csrfmiddlewaretoken, csrf_token)) ```

drf 认证 authentication

认证类如何设置
全局、局部、单个请求如何配置
认证流程