CBV 基本使用
视图函数的本质是接收一个httprequest 对象,返回httpresponse 对象,fbv就是这么一个函数,cbv的as_view() 也是返回这么一个函数。
from django.shortcuts import render,HttpResponse
from django.views import View
class 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_allowed
return 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' if
it 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 token
return {'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 这个值为True
request.META["CSRF_COOKIE_USED"] = True
return _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
# 上面设置了 这边值为True
if not request.META.get("CSRF_COOKIE_USED", False):
return response
if 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 = True
return response
在 process_view 里验证 csrf 是否一致 ```python
页面 {% csrf_token %} 设置的
csrfmiddlewaretoken = “dGZNEIV1rwUbMJA4EDRHaJGHHydZLVEFv9NlvurLtj30vzr8rVuwh71Pe0miHEDf”
cookie 里取的
csrf_token = “8JDrBEx0K2ia0KFGaYGCg9mYmzYANFMtqcrZsq3KMPrZJAwKXgjrnxH6T17TJoL3”
比较两边一致
print(_compare_salted_tokens(csrfmiddlewaretoken, csrf_token)) ```
drf 认证 authentication
认证类如何设置
全局、局部、单个请求如何配置
认证流程