Django 11

Functional Configuration Design

  • Achieve similar in settings.py django middleware strings, a string comment, so that the corresponding function failure

  • importlib Module

# 可以利用 特定格式的字符串路径 导入模块
import importlib
path_str = 'lib.test'
mod = importlib.import_module(path_str)  # from lib import test
'''
文件结构
notify
    __init__.py
    email.py
    msg.py
    wechat.py
settings.py
start.py    
'''
# __init__.py
import settings
import importlib


def send_all(content):
    for path_str in settings.NOTIFY_LIST:
        module_path, class_name = path_str.rsplit('.', maxsplit=1)
        # 拿到文件对象
        mod = importlib.import_module(module_path)  # from notify import email/msg/wechat
        # 利用反射获取文件对象中的类
        cls = getattr(mod, class_name)
        # 实例化对象
        obj = cls(content)
        # 发送通知 (鸭子类型思想, 不管你是什么对象, 都有send方法)
        obj.send()

# email.py
class Email(object):
    def __init__(self, content):
        self.content = content

    def send(self):
        print(f'邮箱通知:{self.content}')
        
# msg.py
class Msg(object):
    def __init__(self, content):
        self.content = content

    def send(self):
        print(f'短信通知:{self.content}')
        
   
# wechat.py
class WeChat(object):
    def __init__(self, content):
        self.content = content

    def send(self):
        print(f'微信通知:{self.content}')



# settings.py 
NOTIFY_LIST = [
    'notify.email.Email',
    'notify.msg.Msg',
    'notify.wechat.WeChat',
]

# start.py
from notify import *

if __name__ == '__main__':
    send_all('非常高兴的通知大家, 本周六加班')
    
    
'''
邮箱通知:非常高兴的通知大家, 本周六加班
短信通知:非常高兴的通知大家, 本周六加班
微信通知:非常高兴的通知大家, 本周六加班
'''

CSRF CSRF

What is CSRF

What is an example of cross-site request forgery it? A simple phishing website

We wrote a shining page exactly the same page of a bank, then the user will "catch" to this page to transfer our operations

A user name, password, and other accounts, as well as transfer amount, submitted

We then use the code written in advance of the "other accounts" to our own account

And then submit a request to a bank interface corresponding to the original page

So users quietly transferred the money on our account the ...

  • Is modeled on the form of a Web page to submit data on the back end, submit a request to its back-end

If you implement CSRF

  • User input "other accounts" of the input tag, the name attribute is not set, so you get less than the corresponding back-end data
  • Use a hidden input tag, set the name attribute, the default is our own account
  • Such backend can only get the value of the hidden input to carry the label
{#向真实网站接口提交请求#}
form action="http://127.0.0.1:8000/transfer/" method="post">
    <p>username <input type="text" name="username"></p>

    {#用户实际需要输入的标签,没有name属性#}
    <p>target_account<input type="text"></p>

    {#隐藏的标签, 有name属性和默认值#}
    <p><input type="text" value="bigb" name="target_account" style="display: none"></p>

    <p>money<input type="text" name="money"></p>
    <input type="submit">
</form>

How to Avoid CSRF

  • Solution: only handle post their own web page request sent ---> How to determine post a request from their own web pages

    ---> Add a hidden input box in return html page form form, carries a random string

    ---> Middleware rear random string to determine whether this is a request sent from this site

  • form form

{#直接在form表单中添加 {% csrf_token %} 即可#}
<form action="" method="post">
    {% csrf_token %}
    <p>username <input type="text" name="username"></p>
    <p>target_account<input type="text" name="target_account"></p>
    <p>money<input type="text" name="money"></p>
    <input type="submit">
</form>

{#然后我们在前端检查代码, 会发现多了个隐藏的input标签#}
<input type="hidden" name="csrfmiddlewaretoken" value="eYT1yNAroJidl3qjDSLSe3U2o0OTQXjD8PcSb2crNDTQijAGjRHX7ual6Y9bLg4D">
  • ajax
{#方式一: 将这个随机字符串添加到ajax向后端提交的data当中即可#}
{% csrf_token %}
<script>
    $('#d1').click(function () {
        $.ajax({
            url: '',
            type: 'post',
            
            //方式一: 利用标签的name属性查找标签并获取对应的随机字符串
            data:{'username':'bigb', 'csrfmiddlewaretoken':$('input[name='csrfmiddlewaretoken']').val()}
            
             //方式二: 'csrfmiddlewaretoken':'{{ csrf_token }}'
            data:{'username':'bigb', 'csrfmiddlewaretoken':'{{ csrf_token }}'}
            success: function (data) {   
            }
        })
    })</script>

{#方式二: 将如下代码放入一个静态js文件中, 再在html文件引入即可#}
//获取
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);
        }
    }
});

CSRF related to two decorators

  • Import: from django.views.decorators.csrf import csrf_exempt, csrf_protect

  • csrf_exempt: The view function is not a page corresponding check csrf
  • csrf_protect: The view function corresponding pages check csrf

from django.views.decorators.csrf import csrf_exempt, csrf_protect

@csrf_exempt  # 不校验
def index(request):
    return HttpResponse('index')

@csrf_protect  # 校验
def index(request):
    return HttpResponse('index')
  • Both the installation is mounted on CBV
    • csrf_exempt can only take effect to the dispatch method to install
    • csrf_protect how equipment can be
from django.views.decorators.csrf import csrf_exempt, csrf_protect

class MyIndex(views.View):
    @method_decorator(csrf_exempt)  # csrf_exempt只能给dispatch方法装才能生效
    def dispatch(self, request, *args, **kwargs):
        return super().dispatch(request, *args, **kwargs)
    
    def get(self, request):
        renturn render(request, 'index.html')
        
    @method_decorator(csrf_protect)  # csrf_protect三种方法都可以     
    def post(self, request):
        return HttpResponse('index')

auth module

Common method

  • Create an administrator user
#命令行输入 : python manage.py makesuperuser
  • Common method
# 1.创建用户(注册)
    # 导入模块
        from django.contrib.auth.models import User
    # 创建普通用户 creatr_user
        User.objects.create_user(username=username, password=password)
    # 创建管理员用户 creater_superuser
        User.objects.create_superuser(username=username, password=password, email=email)
 

# 2.校验用户名和密码是否正确(登录)
    # 导入模块
        from django.contrib import auth
    # 必须传入username和password, 返回用户对象
         user_obj = auth.authenticate(request, username=username, password=password)
            if user_obj:
                return HttpResponse('登录成功!')
            else:
                return HttpResponse('密码或用户错误!')
        
# 3.保存用户状态(session)
    # 执行该代码后, 后面就可以通过 request.user 获取当前登录的用户对象
        auth.login(request, user_obj)
    
# 4.判断用户是否登录
    request.user.is_authenticated()
    
# 5.校验原密码是否正确(修改密码时需要先输入原密码) 
    request.user.check_password(old_password)
    
# 6.修改密码
    request.user.set_password(new_password)
    
# 7.注销
    auth.logout(request)
    
# 8. 登录认证装饰器
    # 导入模块
        from django.contrib.auth.decorators import login_required
    # 局部配置跳转地址
        @login_required(login_url='/login/')
        def index(request):
            return HttpRespone('index')
    # 全局配置配置跳转地址
        # 在settings.py中配置
        LOGIN_URL = /'login'/
        
        @login_required
        def index(request):
            return HttpRespone('index')      

Auth_user extended fields in the table

# 1.利用一对一表关系扩展字段
    class UserDetail(models.Model):
        phone = models.CharField(max_length=11)
        addr = models.CharField(max_length=255)
        
        user = models.OneToOneField(to='User')
        
        
# 2.利用面向对象的继承新建一个表, 替换掉原来的User表
    from django.contrib.auth.models import AbstractUser
    
    # 继承了AbstracterUser中所有的字段
    class UserInfo(AbstractUser):  
    # 扩展字段
    phone = models.CharField(max_length=11)
    addr = models.CharField(max_length=255)
    
    # 需要在settigs.py中将默认表指定为UserInfo
    AUTH_USER_MODEL = 'app01.Userinfo'  # 应用名.表名

Guess you like

Origin www.cnblogs.com/bigb/p/11992979.html