ディレクトリ
まず、ミドルウェアを達成するためのアイデアをプログラミングアナログ
(A)impotlibモジュール
- importlibモジュールは、モジュールの列の形で導入することができます
- importlibモジュールもサポートしています
notify.email
···インポートから型を - ファイル名にのみ最小単位、変数名は、インポートファイルで使用することはできません
# importlib模块(以导入json模块为例)
import importlib
json = importlib.import_module('json')
module = importlib.import_module('notify.email')
(ii)の機能的構成の使用を実現します
- アイデアのDjangoミドルウェアに基づいて設定するための機能を使用してください
- あなたはキャンセルまたは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('明天放假')
第二に、クロスサイトリクエストフォージェリのCSRF
(A)の起源
一例として、フィッシングサイトへの転送:
- 偽のWebサイトを作成し、ユーザーが名前のないタグ属性iniput他のアカウントに記入することができます
- 隠された入力タグの内部では、自身のアカウントの値をname属性を持っています
- この時の提出、自分のアカウントのアカウントを取得するバックエンドの目標では、釣りを形成します
そのため、CSRFは、この問題を解決することです
- ユーザーが返すフォームを形成する際に、Webサイトは、自動値はランダムな文字列が入力されるタグを、非表示にします
- 各ブラウザには、ユニークなランダムな文字列を送信します
- これにより、このへのアクセスの問題を解決します
(B)CSRFの形を形成します
- 唯一の形で{%csrf_token%}を記述する必要が
- ブラウザ隠されたinputタグ
name="csrfmiddlewaretoken"
- すべてのリフレッシュ、値の値が異なることになります
<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">
CSRFにおける(C)AJAX
(1)データによって運ば
- HTMLページのどこに書かれた{%Csrf_tokenの%}
- データのランダムな文字列でラベルを探しに追加すると、AJAXオブジェクトまたはテンプレートの構文を直接呼び出すことができます
data:{'username':'jason','csrfmiddlewaretoken':$('input[name="csrfmiddlewaretoken"]').val()},
data:{'username':'jason','csrfmiddlewaretoken':'{{ csrf_token }}'},
(2)ヘッダを運びます
リターンにより取得されたクッキー文字列は、要求は、ヘッダ内に配置されます
$.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)ファイルの公式ウェブサイト(推奨される使用)を提供
- 任意のJSファイル名(setup.js例)フォルダの静的を作成する、次のコードをコピー
- ページ内のjsファイルをインポートします
# 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関連デコレータ
- 部分:局所検証セットのためのCSRF関連するデコレータやCSRFをキャンセル
- グローバル:CSRFミドルウェアdjango.middleware.csrf.CsrfViewMiddlewareでチェックを設定または解除します
(1)MTVモデルを用いて
- 輸入デコレータする必要があります
- @csrf_protect:機能の設定が飾られているCSRF(クロスサイトリクエストフォージェリ)チェック
- @csrf_exempt:装飾的な機能のCSRF(クロスサイトリクエストフォージェリを)キャンセルキャンセル
from django.views.decorators.csrf import csrf_exempt,csrf_protect
(2)CBVモデルを用いて
- 使用が有効になることができます4つのデコレータのCBVデコレータcsrf_protect、
- csrf_exemptデコレータは発送のみのために有効にするためにインストールすることができます
# 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')
三、Djangoのモジュール認証
(A)認証モジュールとは何ですか
- Djangoの認証モジュールを内蔵しているユーザーの認証モジュールに実装することができ、ユーザのログイン、登録、認証、キャンセル、変更、パスワードやその他の機能が含まれます
- デフォルトのユーザーデータテーブル記憶AUTH_USER
- 最初のインポートを使用する前に
from django.contrib import auth
(ii)の一般的な方法
(1)ユーザの作成
- create_superuser():スーパーユーザを作成し、必要なパラメータには、ユーザー名、パスワード、電子メール
- CREATE_USER():通常のユーザーを作成し、必要なパラメータは、ユーザ名、パスワード
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)ユーザをベリファイ
- 認証():2つのキーワード引数パスワード、正しい、あなたはユーザ名を必要とするユーザー名とパスワードを確認し、正しく空そうでない場合は、Userオブジェクトを返します。
from django.contrib import auth
user_obj = auth.authenticate(request,username=username,password=password)
# 必须传用户名和密码两个参数缺一不能
(3)ログインして保存し
- ログイン(HttpRequestの、ユーザー):ユーザーのログインおよび電流がログオンして保存ユーザーオブジェクト、状態を保存するには、からrequest.user経由で取得することができます
auth.login(request,user_obj)
# 只要这句话执行了 后面在任意位置 只要你能拿到request你就可以通过request.user获取到当前登录的用户对象
(4)ログインするかどうか
- is_authenticated():現在のリクエストが認証されているか否かを判定する
request.user.is_authenticated()
(5)テスト用パスワード
- check_password(パスワード):パスワードを確認するには、ある正しい方法は、現在のユーザの要求のパスワードを提供する必要性は、ブール値を返します。
request.user.check_password(old_password)
(6)パスワード変更
- set_password(パスワード):あなたが保存し、保存を使用するために覚えておく必要があります変更した後、パスワードを設定します
request.user.set_password(new_password)
request.user.save() # 千万不要忘了
(7)キャンセル
- ログアウト(リクエスト):現在の要求のクリアすべてのセッション情報、ノーリターン値
auth.logout(request)
(8)ログ監視デコレータ
- login_requierd():ログインチェックデコレータ、あなたは変数を追加することができますが、ログインページにジャンプしない特定の状況をLOGIN_URL
- ローカル設定:カッコ内の直接のページを追加したアドレス
- グローバル設定:設定ファイルの構成パラメータ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
# 如果全局配置了 局部也配置 以局部的为准
方法(9)ユーザオブジェクト
- 私はs_staff:ユーザーが管理者権限のウェブサイトを持っているかどうか
- is_active:Falseにユーザーのログイン、セットを許可するかどうかは、ユーザーの構内を削除せずにログインするからユーザーを停止することができます。
(III)は、デフォルトのテーブルAUTH_USERを拡張します
(1)1つの外部キー
1つの外部キーフィールドの関係によってフィールドを拡張
class UserDetail(models.Model):
phone = models.BigIntegerField()
user = models.OneToOneField(to='User')
(2)遺伝
- カスタムAbstractUser Modelクラスの連続を建て(インポートする必要があります)
- 設定の設定ファイルがAUTH_USER_MODELパラメータである(アプリケーション名テーブル名)
# 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' # 应用名.表名
第四に、Djangoの設定でソースコード
- 2つのDjangoのプロファイル、内部グローバル、ユーザ定義があります。
- ユーザーが設定されている場合は、それ以外の場合は内部グローバル設定、この設定を使用します
アイデアの実現は:かつての重複したエントリの上に、オブジェクトを与えるために、一度、後者を対象にグローバルコンフィギュレーション設定をロードし、ローカル構成設定をロードします
プラグインの設計前のドキュメント
ソースベースの設定は、実装ファイルプラグインのデザインをデザインに影響を与えました
# 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)