CBV 基本使用
视图函数的本质是接收一个httprequest 对象,返回httpresponse 对象,fbv就是这么一个函数,cbv的as_view() 也是返回这么一个函数。
from django.shortcuts import render,HttpResponsefrom django.views import Viewclass Login(View):def get(self,request):return HttpResponse("GET 方法")def post(self,request):user = request.POST.get("user")pwd = request.POST.get("pwd")if user == "runoob" and pwd == "123456":return HttpResponse("POST 方法")else:return HttpResponse("POST 方法 1")
利用反射,get请求对应 类里的get 方法,post请求对应post 方法
def dispatch(self, request, *args, **kwargs):# Try to dispatch to the right method; if a method doesn't exist,# defer to the error handler. Also defer to the error handler if the# request method isn't on the approved list.if request.method.lower() in self.http_method_names:# 关键反射handler = getattr(self, request.method.lower(), self.http_method_not_allowed)else:handler = self.http_method_not_allowedreturn handler(request, *args, **kwargs)
流程:
url方法 -> view方法 -> dispath方法 (反射方法 get/post/delete/put )
CSRF原理
从使用反推。
模板中如何添加 csrfmiddlewaretoken
cookie 中如何设置 csrftoken
两个值在什么时候验证是否一致
- 模板文件添加 {% csrf_token %}
这部分代码在 django.template.defaulttags
def csrf(request):"""Context processor that provides a CSRF token, or the string 'NOTPROVIDED' ifit has not been provided by either a view decorator or the middleware"""def _get_val():# 调用 中间件 csrf 里的 get_token()token = get_token(request)if token is None:# In order to be able to provide debugging info in the# case of misconfiguration, we use a sentinel value# instead of returning an empty dict.return 'NOTPROVIDED'else:return tokenreturn {'csrf_token': SimpleLazyObject(_get_val)}
调用中间件的csrf 里的 get_token()
def get_token(request):if "CSRF_COOKIE" not in request.META:csrf_secret = _get_new_csrf_string()request.META["CSRF_COOKIE"] = _salt_cipher_secret(csrf_secret)else:csrf_secret = _unsalt_cipher_token(request.META["CSRF_COOKIE"])# 关键,通过设置 CSRF_COOKIE_USED 这个值为Truerequest.META["CSRF_COOKIE_USED"] = Truereturn _salt_cipher_secret(csrf_secret)
在 csrf 中间件里的 process_response 里,设置 cookie 里的 csrftoken
def process_response(self, request, response):if not getattr(request, 'csrf_cookie_needs_reset', False):if getattr(response, 'csrf_cookie_set', False):return response# 上面设置了 这边值为Trueif not request.META.get("CSRF_COOKIE_USED", False):return responseif settings.CSRF_USE_SESSIONS:if request.session.get(CSRF_SESSION_KEY) != request.META['CSRF_COOKIE']:request.session[CSRF_SESSION_KEY] = request.META['CSRF_COOKIE']else:response.set_cookie(settings.CSRF_COOKIE_NAME,request.META['CSRF_COOKIE'],max_age=settings.CSRF_COOKIE_AGE,domain=settings.CSRF_COOKIE_DOMAIN,path=settings.CSRF_COOKIE_PATH,secure=settings.CSRF_COOKIE_SECURE,httponly=settings.CSRF_COOKIE_HTTPONLY,samesite=settings.CSRF_COOKIE_SAMESITE,)# Set the Vary header since content varies with the CSRF cookie.patch_vary_headers(response, ('Cookie',))response.csrf_cookie_set = Truereturn response
在 process_view 里验证 csrf 是否一致 ```python
页面 {% csrf_token %} 设置的
csrfmiddlewaretoken = “dGZNEIV1rwUbMJA4EDRHaJGHHydZLVEFv9NlvurLtj30vzr8rVuwh71Pe0miHEDf”
cookie 里取的
csrf_token = “8JDrBEx0K2ia0KFGaYGCg9mYmzYANFMtqcrZsq3KMPrZJAwKXgjrnxH6T17TJoL3”
比较两边一致
print(_compare_salted_tokens(csrfmiddlewaretoken, csrf_token)) ```
drf 认证 authentication
认证类如何设置
全局、局部、单个请求如何配置
认证流程
