CSRF and auth module

First, the analog programming ideas to achieve Middleware

(A) impotlib module

  1. importlib module may be introduced in the form of a string of modules
  2. importlib module also supports notify.emailthe type from ··· import
  3. Only the smallest unit to the file name, the variable name can not be used in the import file
# importlib模块(以导入json模块为例)
import importlib
json = importlib.import_module('json')

module = importlib.import_module('notify.email')

(Ii) the use of functional configuration realized

  1. Use functions for configuration based on the idea Django middleware
  2. You can cancel or add dynamic functions to achieve a comment by a string in the settings.py
# settings.py
NOTIFY_LIST = [
    'notify.email.Email',
    'notify.msg.Msg',
    'notify.wechat.WeChat',
    'notify.qq.Qq',
]
# noyify/eamil.py
class Email(object):
    def __init__(self):
        pass  # 发送邮件需要的前期准备

    def send(self,content):
        print('邮件通知:%s'%content)
# noyify/msg.py
class Msg(object):
    def __init__(self):
        pass  # 发送短信需要的前期准备

    def send(self,content):
        print('短信通知:%s'%content)
# noyify/wechat.py
class WeChat(object):
    def __init__(self):
        pass  # 发送微信需要的前期准备

    def send(self,content):
        print('微信通知:%s'%content)
# noyify/__init__.py
import settings
import importlib

def send_all(content):
    for path in settings.NOTIFY_LIST:
        module_name,cls_name=path.rsplit('.',maxsplit=1)  # 因为import最小单位只能到文件,因此需要将文件路径和类名分隔开
        module = importlib.import_module(module_name)  # 通过importlib导入文件
        cls = getattr(module,cls_name)  # 通过反射获取文件中类
        obj = cls()
        obj.send(content)      
# start.py
from notify import *
send_all('明天放假')

Second, cross-site request forgery CSRF

(A) the origin of

Transfer to phishing sites as an example:

  1. Make a fake Web site, allows users to fill in the other account iniput no name tag attribute
  2. Inside a hidden input tag has a name attribute, value for its own account
  3. At this time submission, back-end goal of obtaining an account of their own account, to form fishing

Therefore, CSRF is to solve this problem

  1. Web site when the user returns to form Form, Auto Hide a input tag, which value is a random string
  2. Each browser sends a random string that is unique
  3. Thereby solving the problem of access to this

(B) form a form of CSRF

  1. Only need to write a {% csrf_token%} in the form
  2. Browser hidden input tagname="csrfmiddlewaretoken"
  3. Every refresh, value value will be different
<form action="" method="post">
    {% csrf_token %}
    <p>username:<input type="text" name="username"></p>
    <p>target_account:<input type="text" name="target_user"></p>
    <p>money:<input type="text" name="money"></p>
    <input type="submit">
</form>

<!--浏览器可以看到的隐藏的input标签-->
<input type="hidden" name="csrfmiddlewaretoken" value="rJ47FeK9T55wavvVJGY6UxdM1kTMHhTqotGfaXjXIK8Ahz2Uvs02yR9T8bBn5q2D">

(C) ajax in CSRF

(1) carried by data

  1. {% Csrf_token%} written in html page anywhere
  2. Adding to look for the label by a random string of data objects ajax or template syntax can be called directly
data:{'username':'jason','csrfmiddlewaretoken':$('input[name="csrfmiddlewaretoken"]').val()},

data:{'username':'jason','csrfmiddlewaretoken':'{{ csrf_token }}'}, 

(2) carry through headers

Cookie string acquired by the return, the request is placed in the header

$.ajax({
  url: "/cookie_ajax/",
  type: "POST",
  headers: {"X-CSRFToken": $.cookie('csrftoken')},  // 从Cookie取csrf_token,并设置ajax请求头
  data: {"username": "Q1mi", "password": 123456},
  success: function (data) {
    console.log(data);
  }
})

(3) file official website provides (recommended usage)

  1. create a static folder any JS file name (setup.js example), the following code Copy
  2. Importing the js file in the page
# jswenjian 
function getCookie(name) {
    var cookieValue = null;
    if (document.cookie && document.cookie !== '') {
        var cookies = document.cookie.split(';');
        for (var i = 0; i < cookies.length; i++) {
            var cookie = jQuery.trim(cookies[i]);
            // Does this cookie string begin with the name we want?
            if (cookie.substring(0, name.length + 1) === (name + '=')) {
                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                break;
            }
        }
    }
    return cookieValue;
}
var csrftoken = getCookie('csrftoken');

function csrfSafeMethod(method) {
  // these HTTP methods do not require CSRF protection
  return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}

$.ajaxSetup({
  beforeSend: function (xhr, settings) {
    if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
      xhr.setRequestHeader("X-CSRFToken", csrftoken);
    }
  }
});

(Iv) CSRF related decorator

  1. Partial: CSRF associated decorators for topical validation set or cancel CSRF
  2. Global: to set or cancel the check by CSRF middleware django.middleware.csrf.CsrfViewMiddleware

Using (1) MTV model

  1. Need to import decorator
  2. @csrf_protect: function setting is decorated CSRF (cross-site request forgery) check
  3. @csrf_exempt: Cancel the decorative function CSRF (cross-site request forgery) Cancel
from django.views.decorators.csrf import csrf_exempt,csrf_protect

Using (2) CBV model

  1. csrf_protect decorator CBV of four decorators use can become effective,
  2. csrf_exempt decorator can only be installed in order to take effect for dispatch
# 1. csrf_protect方式全都可以  跟普通的装饰器装饰CBV一致
# @method_decorator(csrf_protect,name='post')  # 可以
class MyIndex(views.View):
    @method_decorator(csrf_protect)
    def dispatch(self, request, *args, **kwargs):
        return super().dispatch(request,*args,**kwargs)
    def get(self,request):
        return render(request,'transfer.html')
    # @method_decorator(csrf_protect)  # 可以
    def post(self,request):
        return HttpResponse('OK')

# 2. csrf_exempt这个装饰器只能给dispatch装才能生效    
# @method_decorator(csrf_exempt,name='post')  # csrf_exempt不支持该方法
@method_decorator(csrf_exempt,name='dispatch')  # 生效
class MyIndex(views.View):
    # @method_decorator(csrf_exempt)  # 生效
    def dispatch(self, request, *args, **kwargs):
        return super().dispatch(request,*args,**kwargs)
    def get(self,request):
        return render(request,'transfer.html')
    # @method_decorator(csrf_exempt,name='post')  # csrf_exempt不支持该方法
    def post(self,request):
        return HttpResponse('OK')   

Three, Django the module auth

(A) What is the auth module

  1. Django auth module is built-in user authentication module can be implemented include user login, registration, certification, cancellation, change passwords and other functions
  2. Default user data table storage auth_user
  3. Before using the first importfrom django.contrib import auth

(Ii) common method

(1) Create a user

  1. create_superuser (): create a super-user, the necessary parameters username, password, email
  2. create_user (): Create a regular user, the necessary parameters username, password
from django.contrib.auth.models import User
# User.objects.create(username=username,password=password)  # 不可用  密码不是加密的
# User.objects.create_user(username=username,password=password)  # 创建普通用户    密码自动加密
# User.objects.create_superuser(username=username,password=password,email='[email protected]')  # 创建超级用户   需要邮箱数据

(2) verify the user

  • authenticate (): Verify the user name and password are correct, you need username, password two keyword arguments, correctly returns the User object, otherwise empty
from django.contrib import auth
user_obj = auth.authenticate(request,username=username,password=password)
# 必须传用户名和密码两个参数缺一不能

(3) Login to save

  • login (HttpRequest, user): user login and save the state, save the current logged-on user objects can get in through request.user
auth.login(request,user_obj)
# 只要这句话执行了 后面在任意位置 只要你能拿到request你就可以通过request.user获取到当前登录的用户对象

(4) whether the login

  • is_authenticated (): determines whether the current request is certified
request.user.is_authenticated()

(5) test password

  • check_password (password): check the password is correct way, the need to provide a password of the current user's request, returns a Boolean value
request.user.check_password(old_password)

(6) Change Password

  • set_password (password): Set a password after you modify must remember to use Save to save the
request.user.set_password(new_password)
request.user.save()  # 千万不要忘了

(7) cancellation

  • logout (request): Clear all session information for the current request, no return value
auth.logout(request)

(8) Log Inspection decorator

  • login_requierd (): a login check decorator, you can add variables login_url specified circumstances not jump at the login page
    1. Local Configuration: Add Page directly address in brackets
    2. Global Configuration: settings file configuration parameters LOGIN_URL
from django.contrib.auth.decorators import login_required
# 局部配置
    @login_required(login_url='/login/')
    def index(request):
        pass
     
#全局配置
settings配置文件中 直接配置
LOGIN_URL = '/login/'

@login_required
def index(request):
    pass
# 如果全局配置了 局部也配置  以局部的为准

Method (9) User object

  1. i s_staff: whether the user has administrative rights website
  2. is_active: whether to allow user login, set to False, you can stop users from logging in without deleting the user's premises.

(Iii) extend the default table auth_user

(1) one foreign key

Extended field by one foreign key field relationship

class UserDetail(models.Model):
     phone = models.BigIntegerField()
     user = models.OneToOneField(to='User')

(2) inheritance

  1. Custom built a succession of AbstractUser Model class (need to import)
  2. settings configuration file is AUTH_USER_MODEL parameters (application name Table name)
# module.py
from django.contrib.auth.models import AbstractUser

class Userinfo(AbstractUser):
phone = models.BigIntegerField()
register_time = models.DateField(auto_now_add=True)

# settings.py
AUTH_USER_MODEL = 'app01.Userinfo'  # 应用名.表名

Fourth, the source code in Django settings

  1. There are two Django profile, an internal global, a user-defined
  2. If the user is configured, use this configuration, otherwise the internal Global Settings

Realization of ideas: to load the global configuration settings to the subject, and then load the local configuration settings to give the object, once the latter over the former duplicate entries

Documents before the plug-in design

Source-based settings inspired design, implementation file plug-in design

# conf/settings.py
NAME = '我是暴露给用户的自定义配置'
# lib/conf/globa_settings.py
NAME = '我是项目默认的配置文件'
# lib/conf/__init__.py

import importlib
from lib.conf import global_settings
import os

class Settings(object):
    def __init__(self):
        for name in dir(global_settings):
            if name.isupper():
                setattr(self, name, getattr(global_settings, name))
        # 获取暴露给用户的配置文件字符串路径
        module_path = os.environ.get('xxx')
        md = importlib.import_module(module_path)  # md = settings
        for name in dir(md):
            if name.isupper():
                k = name
                v = getattr(md,name)
                setattr(self,k,v)

settings = Settings()
# start.py
import os
import sys


BASE_DIR = os.path.dirname(__file__)
sys.path.append(BASE_DIR)


if __name__ == '__main__':
    # os.environ.setdefault('xxx','conf.settings')
    os.environ['xxx'] = 'conf.settings'  # environ是一个字符串所对应环境的映像对象
    from lib.conf import settings
    print(settings.NAME)

Guess you like

Origin www.cnblogs.com/1012zlb/p/12005976.html