django CBV装饰器 自定义django中间件 csrf跨站请求伪造 auth认证模块
CBV加裝飾器
第一種 @method_decorator(裝飾器) 加在get上
第二種 @method_decorator(login_auth,name='get') 加在類上
第三種 @method_decorator(login_auth) 加在dispatch上 3.7的要return super().dispatch
def login(request):if request.method == 'POST':username = request.POST.get('username')pwd = request.POST.get('pwd')if username == 'jason' and pwd == '123':request.session['name'] = 'jason'return redirect('/home/')return render(request,'login.html')from functools import wraps def login_auth(func):@wraps(func)def inner(request,*args,**kwargs):if request.session.get('name'):return func(request,*args,**kwargs)return redirect('/login/')return inner?導入裝飾器? ? 翻譯?decorators? 裝飾
from django.utils.decorators import method_decorator?
?被裝飾的類
@method_decorator(login_auth,name='get') #第二種 name參數必須指定 class MyHome(View):@method_decorator(login_auth) #第三種 get和post都會被裝飾def dispatch(self,request,*args,**kwargs):super().dispatch(request,*args,**kwargs)@method_decorator(login_auth) #第一種def get(self,request):return HttpResponse('get')def post(self,request):return HttpResponse('post')?
?
?
?自定義django中間件
?什么是中間件?
django請求生命周期完整版,中間件類似于django的門衛,數據在進入和離開時都需要經過中間件
中間件能干嘛?
控制用戶訪問頻率,全局登錄校驗,用戶訪問白名單,黑名單,反爬相關等
?用來幫你全局相關的功能校驗
django默認有7個中間件,但是django暴露給用戶可以自定義中間件并且里面可以寫五種方法?
?
中間件的使用(5個固定的方法)
process_request:請求來的時候從上往下依次執行每一個中間件里面的process_request方法(如果沒有直接通過)
process_request(self,request)?
process_response:響應走的時候會從下往上依次執行每一個中間件里面的process_response方法(如果沒有直接通過)
process_response(self,request,response)return response?
process_view:路由匹配成功執行視圖之前自動觸發(從上往下依次執行)
process_view(self, request, view_func, view_args, view_kwargs)?
process_exception:當視圖函數報錯了,自動觸發(從下往上依次執行)
process_exception(self,request,exception)?
process_template_response:視圖函數返回的對象有一個render()方法(或者表名對象是一個TemplateResponse對象或等價方法)(從上往下依次執行)
process_template_response(self,request,response)return response
?
完整的流程圖
?
?
?自定義中間件
新建一個任意名字的文件夾,里面新建一個任意名字py文件
from django.utils.deprecation import MiddlewareMixin?
?
?
?
class MyMiddleware(MiddlewareMixi):def process_request(self,request):print(''我是第一個自定義中間件里面的process_request方法')#return HttpResponse('heieheihei')def process_response(self,request,response):print('我是第一個自定義中間件里面的process_response方法')return response #必須將response形參接收的數據返回,不然直接報錯def process_view(self,request,view_func,view_args,view_kwargs):print('我是第一個自定義中間件里面的process_view方法')print(view_func.__name__,view_func)def process_exception(self,request,exception):print('我是第一個自定義中間件里面的process_exception方法')print(exception)def process_template_response(self,request,response):print('我是第一個自定義中間件里面的process_template_response方法')return response?
?
?自定義完之后再項目settings.py文件下引用
MIDDLEWARE = ['django.middleware.security.SecurityMiddleware','django.contrib.sessions.middleware.SessionMiddleware','django.middleware.common.CommonMiddleware','django.middleware.csrf.CsrfViewMiddleware','django.contrib.auth.middleware.AuthenticationMiddleware','django.contrib.messages.middleware.MessageMiddleware','django.middleware.clickjacking.XFrameOptionsMiddleware',# 'app01.mymiddleware.mdzz.MyMiddleware', #自定義中間件1 應用.文件夾.自定義py文件.自定義中間件類名# 'app01.mymiddleware.mdzz.MyMiddleware1' #自定義中間件2 ]?
?
?
csrf(跨站請求偽造)
由來:釣魚網站 拿到銀行轉賬的路徑,做一個跟銀行一模一樣的頁面,向銀行轉賬接口提交數據,當用戶在釣魚網站輸入對方賬戶名和轉賬金額之后,點擊發送,其實內部是將對方賬戶換成了釣魚網站的造假人員的賬戶。造成你轉賬轉錯賬戶的情況
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Title</title><script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script><link rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.min.css"><script src="/static/bootstrap-3.3.7/js/bootstrap.min.js"></script> </head> <body> <h1>正經的網站</h1> <form action="/index3/" method="post"> {# {% csrf_token %}#}<p>username:<input type="text" name="username"></p><p>money:<input type="text" name="money"></p><p>others:<input type="text" name="others"></p><input type="submit"> </form> </body> </html> 正常頁面?
釣魚網站提交連接也是銀行的轉賬接口
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Title</title><script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script><link rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.min.css"><script src="/static/bootstrap-3.3.7/js/bootstrap.min.js"></script> </head> <body> <h1>釣魚網站</h1> <form action="http://127.0.0.1:8000/transfer/" method="post"><p>username:<input type="text" name="username"></p><p>money:<input type="text" name="money"></p><p>others:<input type="text"></p><input type="text" name="others" value="jason" style="display:none"><input type="submit"> </form> </body> </html> 釣魚頁面?
?
如何區分釣魚網站和正經網站?在正經網站返回頁面的時候,在form表單中偷偷塞一個特殊的字符串,后端記下該頁面對應的字符串的值,等用戶發post請求來的時候,我先去校驗特殊的字符串是否匹配
如何去寫這個特殊的字符串?
模板語法有一個固定的寫法? ?必須寫在form表單內
{% csrf_token %}?
表單中偷偷塞的特殊的字符串
{% csrf_token %} <input type='hidden' name='csrfmiddlewaretoke' value='"2vzoo1lmSWgLTdI2rBQ4PTptJQKRQTRwnqeWRGcpdAQGagRp8yKg8RX2PdkF4aqh">Ps:value是動態生成的,每一次刷新都不一樣?
?
ajax中如何設置csrf_token? 把k和v放在data里面
<form action="/index3/" method="post"> {# {% csrf_token %}#}<p>username:<input type="text" name="username"></p><p>money:<input type="text" name="money"></p><p>others:<input type="text" name="others"></p><input type="submit"> </form> <button>ajax</button> <script>$('button').click(function () {$.ajax({url:'',type:'post',data:{'name':'jason','csrfmiddlewaretoken':$('[name="csrfmiddlewaretoken"]').val()},success:function (data) {console.log(data)}})}) </script>? 第二種ajax提交 data:{'csrfmiddlewaretoken':'{{ csrf_token}}'}
?
csrf_token導入
form django.views.decorators.csrf import csrf_exempt,csrf_protect?
?
csrf 裝飾FBV
不校驗csrf
@csrf_exempt def index1(request):return HttpResponse('ok')?
校驗csrf
@csrf_protect def index2(request):return HttpResonse('ok')?
?
csrf裝飾給CBV?
先導入裝飾器語法
from django.utils.decorators import method_decorator?
校驗csrf
@method_decorator(csrf_protect,name='post') #第三種 class Index3(View):@method_decorator(csrf_protect) #第二種def dispatch(self,request,*args,**kwargs):super().dispatch(request,*args,**kwargs)def get(self,request):return HttpResponse('get')@method_decortaor(csrf_protect) #第一種def post(self,request):return HttpResponse('post')?
不校驗csrf (只有兩種 每種都是全都不校驗)
@method_decorator(csrf_exempt,name='dispatch') #第二種 class Index3(View):@method_decorator(csrf_exempt) #第一種def dispatch(slef,request,*args,**kwargs):super().dispatch(request,*args,**kwargs)def get(self,request):return HttpResponse('get')def post(self,request):return HttpResponse('post')?
?
csrf裝飾CBV需要注意
csrf_protect 跟正常的CBV裝飾器一樣 三種
csrf_exempt 只能有下面兩種方式
@method_decorator(csrf_exempt,name='dispatch') #一種
class Index3(View):
#@method_decorator(csrf_exempt) #二種
def dispatch(self,request,*args,**kwargs):
super().dispatch(request,*args,**kwargs)
其實都是給dispatch加
?
Auth認證模塊
執行數據庫遷移的那兩命令式,即使我們沒有建表,django也會創建好多張表 auth_user表存放的用戶相關的數據
?
auth_user表記錄的添加
創建超級用戶(不可手動插入,因為密碼是加密的)
可以使用命令行createsuperuser 會讓你輸入用戶名和密碼 但是都是明文輸入
簡單使用auth認證 auth.authenticate(校驗條件)
from django.contrib import auth def login(request):if request.method == 'POST':name = request.POST.get('name')pwd = request.POST.get('pwd')#models.User.objects.filter(username=username,password=pwd)user_obj = auth.authenticate(request,username=username,password=pwd)#authenticate 驗證if user_obj:#設置用戶狀態#request.session['name'] = 'jason'auth.login(request,user_obj) #一旦記錄了 ,可以在任意的地方通過request.user獲取到當前登錄對象return HttpResponse('ok')return render(request,'auth_login.html')?
只要登錄成功執行了auth.login(request,user_obj)
之后在其他任意的視圖函數中都通過request.user獲取當前登錄用戶對象
如果沒有執行auth.login??
request.user打印出來的是匿名用戶
如何判斷request.user用戶是否通過auth.login登錄呢?
request.user.is_authenticated()
?為何auth.login之后,其他視圖函數中就可以通過request.user拿到當前登錄對象呢?
其實就是把用戶信息放到django_session表
?
注銷 auth.logout(request)
def auth_logout(request):auth.logout(request) #等價于request.session.flush()return HttpResponse('ok')?
?
需要找到這張表
from django.contrib.auth.models import User?
?注冊 User.objects.create_user 普通用戶 User.objectes.create_superuser 超級用戶
def auth_register(request):if request.method = 'POST':username = request.POST.get('username')password = request.POST.get('password')user_obj = auth.authenticate(request,username=username)#校驗用戶if user_obj:return HttpResponse('當前用戶已存在')#User.objectes.create(username=username,password=password) 不能再用create創建#User.objects.create_user(username=username,password=password) #創建普通用戶User.objects.create_superuser(username=username,password=password,email='123@163.com') #創建超級用戶return render(request,'auth_register.html')?
?
?更改密碼? request.user.check_password('密碼') 校驗密碼 request.user.set_password('新密碼') 設置新的密碼 request.user.save() 保存
def auth_password(request):print(request.user.password) #密文is_res = request.user.check_password('jason123') #校驗密碼是否一致if is_res:request.user.set_password('666') #設置新密碼request.user.save() #修改密碼必須save保存 不然無效return HttpResponse('ok')?
?
?裝飾器校驗是否登錄及跳轉
?auth裝飾器
from django.contrib.auth.decorators import login_required?
?被裝飾函數
@login_required(login_url='/login/',redirect_field_name = 'old') #沒登錄會跳轉login頁面,并且后面會拼接上你上一次想訪問的頁面路徑/login/?next=/你想訪問的路徑/ 可以通過參數修改next鍵名 def auth_home(request):return HttpResponse('home必須登錄才能訪問')?
如果我所有視圖函數都需要裝飾并跳轉到login頁面,那么我要寫好多份 為了一勞永逸
#可以在項目配置文件中指定auth校驗登錄不合法統一跳轉到某一個路徑 LOGIN_URL = '/login/' #全局配置?
?
自定義模型表引用auth功能
如何擴張auth_user表?
一對一關聯(不推薦)
from django.contrib.auth.model import Userclass UserDetail(models.Model):phone = models.CharField(max_length=11)user = models.OnoToOneField(to=User) #User表在之前創建了 所以可以直接寫to=User?
?
面向對象的繼承
導入語法
from django.contrilb.auth.models import User,AbstractUser?
?
class UserInfo(AbstractUser):phone = models.CharField(max_length=32)avatar = models.CharField(max_length=32)?
?
告訴django不在使用默認的auth_user,而使用我們自己定義的表
語法:AUTH_USER_MODEL= ‘app名.models里面對相應的模型表名’
在項目settings.py文件中配置
AUTH_USER_MODEL= 'app01.UserInfo'?
?
自定義認證系統默認使用的數據表之后,我們我們就可以像使用默認的auth_user表那樣使用我們的UserInfo表了
庫里面也沒有auth_user表了,原來auth表的操作方法,現在全部用自定義的表均可實現
?
轉載于:https://www.cnblogs.com/lakei/p/11048141.html
總結
以上是生活随笔為你收集整理的django CBV装饰器 自定义django中间件 csrf跨站请求伪造 auth认证模块的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: pageContext对象
- 下一篇: 用IntelliJ IDEA 配置安卓(