Python path [Chapter 2]: Django middleware, CSRF, djangocsrf
CSRF
1. Overview
Cross Site Request (CSRF) is a Cross-Site Forgery Request. For example, a malicious website has a link pointing to your website, if a user has logged on to your website, a request will be sent to your website when the user clicks the link on this malicious website, your website will assume that this request was sent by the user. In fact, this request was forged by the malicious website.
To avoid this problem, Django references the CSRF protection mechanism. When Django first responds to a request from a client, a random token is generated on the server, and put the token in the cookie. This token will be added to each POST request to avoid being attacked by CSRF. If the POST request does not contain a random token string, the system returns the 403 Denial of Service.
- In the returned HTTP Response cookie, django will add a csrftoken field for you, whose value is an automatically generated token.
- All POST forms must contain a csrfmiddlewaretoken field (add a tag in the template and django will automatically generate the field for you, as shown below)
- Before processing the POST request, django will verify that the value of the csrftoken field in the cookie in the request is the same as the value of the csrfmiddlewaretoken field in the submitted form. If the request is the same, it indicates that this is a legal request. Otherwise, this request may come from another person's csrf attack and 403 Forbidden is returned.
- Add a X-CSRFTOKEN header in all ajax POST requests whose value is the csrftoken value in the cookie
In settings. py, We need to enable middleware django. middleware. csrf. CsrfViewMiddleware:
MIDDLEWARE = [ 'django.middleware.csrf.CsrfViewMiddleware',]
Local Usage:
- @ Csrf_protect: forces the anti-Cross-Site Request Forgery feature for the current function, even if no global middleware is set in settings.
- @ Csrf_exempt: cancels the current function's Cross-Site Request Forgery Prevention function, even if global middleware is set in settings.
2. Form submission POST request
Process files:
From django. shortcuts import render, HttpResponse, redirect # Create your views here. def login (request): if request. method = 'get': return render(request,'login.html ') elif request. method = 'post': user = request. POST. get ('user') pwd = request. POST. get ('pwd') if user = 'root' and pwd = "123 ": # generate a random string # write it to the user's browser Cookie # Save it to the Session # Set the relevant content in the dictionary corresponding to the random string... request. session ['username'] = user request. session ['if _ login'] = True # You can directly determine the username without adding it. if request is also supported. POST. get ('session ') = '1': # set the time-out time separately. The current session takes effect and the global request is not affected. session. set_expiry (10) #10 seconds return redirect ('/index/') else: return redirect ('/login/') def index (request ): # obtain the random string of the current user # obtain the corresponding information based on the random string if request. session. get ('If _ login'): return render (request, 'index.html ') else: return redirect ('/login /')
Views. py
Login.html file:
{# Add {% csrf_token % }#}<! DOCTYPE html>
3. Submit a POST request using Ajax
Process files:
From django. shortcuts import render, HttpResponse, redirect # Create your views here. def login (request): if request. method = 'get': return render(request,'login.html ') elif request. method = 'post': user = request. POST. get ('user') pwd = request. POST. get ('pwd') if user = 'root' and pwd = "123 ": # generate a random string # write it to the user's browser Cookie # Save it to the Session # Set the relevant content in the dictionary corresponding to the random string... request. session ['username'] = user request. session ['if _ login'] = True # You can directly determine the username without adding it. if request is also supported. POST. get ('session ') = '1': # set the time-out time separately. The current session takes effect and the global request is not affected. session. set_expiry (10) #10 seconds return redirect ('/index/') else: return redirect ('/login/') def index (request ): # obtain the random string of the current user # obtain the corresponding information based on the random string if request. session. get ('If _ login'): return render (request, 'index.html ') else: return redirect ('/login /')
Views. py
Login.html file:
{# Add the headers value when submitting Ajax #}<! DOCTYPE html>
After the preceding html file is submitted and executed successfully, a program usually has more than one Ajax request. Therefore, we need to add headers to each Ajax request, which increases the workload; in this case, global settings are required, so you do not need to add a request header for each request.
{# Global effectiveness when Ajax is submitted #}<! DOCTYPE html> Login.html
<!DOCTYPE html>Official Use example .html
Middleware
1. Overview
Middleware in django is actually a class in django. After the request arrives and ends, django will execute the corresponding methods in the MIDDLEWARE at the right time according to its own rules. In the settings module of the django project, there is a MIDDLEWARE variable, and each element is a MIDDLEWARE, as shown below:
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',]
Four methods can be defined in middleware:
- Process_request (self, request) requests are executed when they are not written. skip this step and execute the next middleware. When return HttpResonse exists, the following middleware will not execute
- Process_view (self, request, callback, callback_args, callback_kwargs) First executes process_request, and then runs proces_view
- Process_template_response (self, request, response) if the object returned by the function in Views has the render method, this method is executed
- Process_exception (self, request, exception) exception triggers execution when views. this method is executed when an error occurs in the execution of the py function. When an error occurs, the exception priority of the lowest layer is the highest, the most recent one is executed, and then the respneuron method is executed.
- Process_response (self, request, response) is executed when the request is returned. skip this step when no write is required and execute the next middleware. When return HttpResonse exists, the original data is replaced.
The returned values of the preceding methods can be None and HttpResonse objects. If the returned values are None, they will continue to be executed in accordance with the rules defined by django. If the returned values are HttpResonse objects, the objects will be directly returned to users.
Note: directly execute process_response at the same level After Django version 1.10, instead of starting execution from process_response at the lowest layer.
2. Custom Middleware
Create the middleware directory (with any name) in the Django main directory and create the m. py file in the directory.
① Process_request and process_response
Customize the middleware class in the file:
From django. utils. deprecation import MiddlewareMixinfrom django. shortcuts import HttpResponseclass Row1 (MiddlewareMixin): def process_request (self, request): print ("Wang Sen 1") # return HttpResponse ("DDDD") def process_response (self, request, response): print ("handle sub-1") return responseclass Row2 (MiddlewareMixin): def process_request (self, request): print ("Wang Sen 2") def process_response (self, request, response): print ("handle sub-3") return responseclass Row3 (MiddlewareMixin): def process_request (self, request): print ("Wang Sen 3") def process_response (self, request, response): print ("handle 3") return response
Register the middleware in the settings file:
from django.middleware.csrf import CsrfViewMiddlewareMIDDLEWARE = [ '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', 'middleware.m.Row1', 'middleware.m.Row2', 'middleware.m.Row3',
Execute print:
Wang Sen 1 Wang Sen 2 Wang Sen 3 walk you carry son 3 carry son 3 carry son 1
Print
② Process_view
Customize the middleware class in the file:
From django. utils. deprecation import MiddlewareMixinfrom django. shortcuts import HttpResponseclass Row1 (outputs): def process_request (self, request): print ("Wang Sen 1") def process_view (self, request, view_func, view_func_args, view_func_kwargs ): print ("James1") def process_response (self, request, response): print ("handle sub-1") return responseclass Row2 (MiddlewareMixin): def process_request (self, request ): print ("Wang Sen 2") def process_view (self, request, view_func, view_func_args, view_func_kwargs): print ("James2") def process_response (self, request, response ): print ("handle sub-3") return responseclass Row3 (MiddlewareMixin): def process_request (self, request): print ("Wang Sen 3") def process_view (self, request, view_func, view_func_args, view_func_kwargs): print ("James3") def process_response (self, request, response): print ("handle sub-3") return response
Execute print:
Wang Sen 1 Wang Sen 2 Wang Sen 3James1James2James3 walk you carry son 3 carry son 3 carry son 1
Print