ジャンゴ11

機能構成デザイン

  • その対応する機能の障害という、文字列のコメント、settings.pyはDjangoミドルウェアの文字列に似て達成

  • importlib モジュール

# 可以利用 特定格式的字符串路径 导入模块
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

CSRFとは何ですか

クロスサイトリクエストフォージェリそれ?Aの簡単なフィッシングサイトの例は何ですか

私たちは、その後、ユーザーがこのページへの「キャッチ」事業を譲渡することになる、銀行のまったく同じページ輝いページを書きました

提出されたユーザ名、パスワード、および他のアカウントだけでなく、転送量、

私たちは、その後、私たち自身のアカウントに「他のアカウント」の前に書かれたコードを使用します

そして、元のページに対応するインターフェイス銀行に要求を提出

だから、ユーザーが静かに私たちの口座にお金を転送しました...

  • バックエンドにデータを提出するために、Webページのフォームにモデル化され、そのバックエンドに要求を提出

あなたはCSRFを実装する場合

  • あなたはあまり対応するバックエンドのデータより取得するように、ユーザ入力inputタグの「他のアカウントは」、name属性は、設定されていません
  • デフォルトでは、私たち自身のアカウントで、name属性を設定し、隠された入力タグを使用します
  • このようなバックエンドはラベルのみを運ぶために隠された入力の値を取得することができます
{#向真实网站接口提交请求#}
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>

CSRFを回避する方法

  • ソリューション:だけ自分のWebページ要求て送信を投稿扱う--->どのように自分のWebページからのリクエストを投稿し決定します

    --->リターンhtmlページのフォームフォームの中に隠された入力ボックスを追加し、ランダムな文字列を運びます

    これは、このサイトから送信された要求であるかどうかを判断する--->ミドルウェアリアランダムな文字列

  • フォームフォーム

{#直接在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向后端提交的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);
        }
    }
});

2つのデコレータに関連CSRF

  • インポート: from django.views.decorators.csrf import csrf_exempt, csrf_protect

  • csrf_exempt:ビュー機能は、ページ対応するチェックCSRFではありません
  • csrf_protect:ビュー機能に対応するページは、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')
  • どちらのインストールには、CBVに搭載されています
    • csrf_exemptだけでインストールするには、発送方法に影響を取ることができます
    • 機器がいかにcsrf_protect
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')

認証モジュール

一般的な方法

  • 管理者ユーザーを作成します。
#命令行输入 : python manage.py makesuperuser
  • 一般的な方法
# 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は、テーブルのフィールドを拡張しました

# 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'  # 应用名.表名

おすすめ

転載: www.cnblogs.com/bigb/p/11992979.html