Django- middleware, csrf (CSRF), auth authentication module

django middleware

What is middleware?

django request the full version of the life cycle, similar to the guard django middleware, the data when entering and leaving the need to go through middleware

Middleware Why?

Control user access frequency, global landing check, the user access to the white list, black list, etc.

View django default of three middleware

  • Csrf
  • Session
  • Auth

Using middleware (5 fixed method)

Custom Middleware

from django.utils.deprecation import MiddlewareMixin


class MyMiddleWare(MiddlewareMixin):
    def process_request(self, request):
        print('我是第一个自定义的中间件的process_request!')
# 写一个路由与视图,启动项目,查看打印结果。
# 再写一个自定义中间件

class MyMiddleWare(MiddlewareMixin):
    def process_request(self, request):
        print('我是第二个自定义的中间件的process_request!')
# 诠释中间件的执行顺序


# 在两个中间件中添加process_response方法。研究中间件消息进出的顺序
class MyMiddleWare(MiddlewareMixin):
    def process_request(self, request):
        print('我是第一个自定义的中间件的process_request!')
    def process_response(self,request,response):
        print('我是第一个自定义的中间件的process_response')
        return response
# 再来研究process_request中直接返回HttpReponse对象,会怎么走接下来的process_response

# process_view,process_exception,process_template_response

Custom middleware

Middleware can define five methods, namely :( main thing is process_request and process_response)

  • process_request(self,request)
  • process_view(self, request, view_func, view_args, view_kwargs)
  • process_response(self, request, response)

Return value None of the above method may be a HttpResponse object or, if is None, then proceed back to continue according to the rules defined django, if HttpResponse object, the object is returned directly to the user.

process_request

process_request has one parameter, the request, the request and view function is the same as in the request (prior to routing Django later, this request object on a series of operations).

Since the request object is the same, so we can perform series of operations on the request object, comprising a request. Variable name = variable value, such operations, we can view acquired in a subsequent function in the same manner as in our value set in the middleware.

Its return value can be None can be HttpResponse object. The return value is None, then the normal process to continue to go to the next middleware processing, if it is HttpResponse object, Django view function will not be performed, and the corresponding object is returned to the browser.

process_response

process_response method multiple middleware is registered in accordance with MIDDLEWARE in reverse order of execution, that is the first middleware process_request method is performed first, and its final implementation process_response method, the last method middleware last process_request execution, its process_response method is executed first.

process_view

process_view(self, request, view_func, view_args, view_kwargs)

The method takes four parameters

  • request is the HttpRequest object.
  • view_func is Django view function that will be used. (Which is actually a function of the object, rather than as a function of the name string.)
  • view_args list is passed to the position of the view parameters.
  • view_kwargs is passed to the dictionary key parameters of view. view_args and view_kwargs not contain the first view parameter (request).

Django calls the view process_view method before calling the function.

It should return None or an HttpResponse object. If it returns None, Django will continue to process the request, the middleware process_view perform any other method, and then perform a corresponding view. If it returns an HttpResponse object, Django will not perform the function of a view, but the U-turn directly in middleware, flashbacks perform one process_response method, and finally returned to the browser

Middleware implementation process

After the request arrives at the middleware, the implementation of the first intermediate process_request method according to each registered positive sequence, process_request method returns the value of None, it is sequentially performed, if the value returned is HttpResponse object, the latter method is not executed process_request, but process_response execution of the current method corresponds middleware (Note that not all process_response method to perform a U-turn), the HttpResponse object returned to the browser. In other words: If MIDDLEWARE registered six middleware, the implementation process, the first three middleware returns an HttpResponse object, 4,5,6 middleware process_request and process_response methods are not implemented, the implementation of the order of 3 , process_response method 2,1 middleware.

ZOZRu4.png

process_request methods are executed, the matching route, find the view functions to be performed, the first view is not executed function, perform process_view method middleware, process_view method returns None, continue with the order, all process_view method of execution after execution view function. If intermediate 3 process_view method returns HttpResponse object, and the view of the 4,5,6 process_view functions are not executed, from the last intermediate, intermediate process_response method is reverse 6 begins execution directly.

ZOZWDJ.png

CSRF (cross-site request forgery)

To write a simple post request, to reproduce the error message

Phishing sites: bank transfer path, you also can get, then you do exactly the same with a bank page, also submit data over the bank's excuse, after you enter each other's account name and transfer amount in phishing sites, click Send. In fact, the interior is replaced by the other account account fraud personnel of phishing sites. Resulting in transfer cases you turn the wrong account

Django open two projects, simulation transfer phenomenon

How to distinguish phishing sites and decent website? In return decent website page when, in the form secretly plug form a special string, the back-end record value corresponding string change page, and other users send post request, I went to a special check character string match

How to write this particular string of it? A fixed template grammar written {% csrf_token%}, the form must be written in the form

Browser to view the value of the label change, and every refresh. Demo again just transfers

ajax how to set csrf_token

# 第一种页面上先写一个{%csrf_token%}标签,后面用jquery查找标签取值组成键值对放入data中即可

csrf_token topical use

# 只想给某个视图韩式加上csrf校验
from django.views.decorators.csrf import csrf_exempt,csrf_protect

# 局部禁用
@csrf_exempt
def index(request):
  pass

# 局部使用
@csrf_protect
def login(request):
  pass

# CBV比较特殊,不能单独加在某个方法上
# 只能加在类上或dispatch方法上
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt,csrf_protect
@method_decorator(csrf_exempt,name='get')  # 第一种
class Csrf_Token(View):
  @method_decorator(csrf_exempt)  # 第二种
  def dispatch(self,request,*args,**kwargs):
    res = super().dispatch(request,*args,**kwargs)
    return res
  @method_decorator(csrf_exempt)  # 这里这么写不行!!!
  def get(self,request):
    pass
  def post(self,request):
    pass

Auth authentication module

When performing database migration that two commands, even if we do not build the table, django is not also create a lot of tables? We take a look inside After you create a table called auth_user, since it is a table, it is certainly there should be a corresponding change operation table method

Add auth_user table records

  • Create a super user (not manually inserted, because the password is encrypted)

  • Simple to use auth certification

    from django.contrib import auth
    def login(request):
      if request.method == 'POST':
        name = request.POST.get('name')
        pwd = request.POST.get('pwd')
        user = auth.authenticate(request,username=name,password=pwd)
        # 类似于user=models.User.objects.filter(username=name,password=pwd).first()
        if user:
          return redirect('/home/')
      return render(request,'login.html')
  • Simply not verify the information, you also need to save the user's current successful landing of the landing state, before a cookie or by session, it is now, auth also provides you with a more useful method

    if user:
      # 等价于request.session['name']=name
      auth.login(request,user)  # 登陆,其实就把用户信息放到session中,跑一下验证session表
  • In fact, the above authentication and landing than its highlights, highlights that

    # 只要登陆成功执行了auth.login(request,user)
    # 之后在其他任意的视图函数中都通过request.user获取当前登陆用户对象
    
    # 当没有执行auth.login,request.user打印出来的是匿名用户。将session表数据删除即可演示改效果
    # 如何判断request.user用户是否通过auth.login登陆呢?request.user.is_authenticated
    
    # 为何执行auth.login之后,其他视图函数中就可以通过request.user拿到当前登陆对象呢?想想django的中间件中有没有一个叫Auth啥的中间件,它干了件什么事,能不能推导一下?取出session去表里面查相应的数据,然后放到request.user中,点进去看一下这个中间件确实如此
  • Logout

    auth.logout(request)
    # 等价于删除session数据request.session.flush()
  • Decorator check whether the landing and jump

    from django.contrib.auth.decorators import login_required
    
    @login_required(login_url='/login/',redirect_field_name='old')  # 没登陆会跳转到login页面,并且后面会拼接上你上一次想访问的页面路径/login/?next=/test/,可以通过参数修改next键名
    def my_view(request):
      pass
  • If all the functions need to decorate my view and jump to the login page, then I need to write a lot of copies

    # 可以在配置文件中指定auth校验登陆不合法统一跳转到某个路径
    LOGIN_URL = '/login/'  # 既可以局部配置,也可以全局配置
  • Back to the top, we are how to add data to auth_user table? ~ ~ ~ Command line is not reasonable?

    from django.contrib.auth.models import User
    def register(request):
      User.objects.create()  # 不能用这个,因为密码是明文
      User.objects.createuser()  # 创建普通用户
      User.objects.createsuperuser()  # 创建超级用户
  • Check passwords, change passwords

    request.user.check_password(pwd)  # 为什么不直接获取查,因为前端用户输入的是明文数据库密文
    
    request.user.set_password(pwd)
    request.user.save()  # 修改密码

Custom application auth function model table

How to expand auth_user table?

  • One association (not recommended)

    from django.contrib.auth.model s import User
    
    class UserDetail(models.Models):
      phone = models.CharField(max_length=11)
      user = models.OnoToOneField(to=User)
  • Object-oriented inheritance

    from django.contrib.auth.models import User,AbstractUser
    class UserInfo(AbstractUser):
      phone = models.CharField(max_length=32)
    
    # 需要在配置文件中,指定我不再使用默认的auth_user表而是使用我自己创建的Userinfo表
    AUTH_USER_MODEL = "app名.models里面对应的模型表名"
    
    
    """
    自定义认证系统默认使用的数据表之后,我们就可以像使用默认的auth_user表那样使用我们的UserInfo表了。
    库里面也没有auth_user表了,原来auth表的操作方法,现在全部用自定义的表均可实现
    """

Guess you like

Origin www.cnblogs.com/gaohuayan/p/11368494.html