日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

django CBV装饰器 自定义django中间件 csrf跨站请求伪造 auth认证模块

發(fā)布時(shí)間:2025/3/15 55 豆豆
生活随笔 收集整理的這篇文章主要介紹了 django CBV装饰器 自定义django中间件 csrf跨站请求伪造 auth认证模块 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

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

?導(dǎo)入裝飾器? ?  翻譯?decorators? 裝飾

from django.utils.decorators import method_decorator

?

?被裝飾的類

@method_decorator(login_auth,name='get') #第二種 name參數(shù)必須指定 class MyHome(View):@method_decorator(login_auth) #第三種 get和post都會(huì)被裝飾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請(qǐng)求生命周期完整版,中間件類似于django的門衛(wèi),數(shù)據(jù)在進(jìn)入和離開時(shí)都需要經(jīng)過中間件

中間件能干嘛?

  控制用戶訪問頻率,全局登錄校驗(yàn),用戶訪問白名單,黑名單,反爬相關(guān)等

    ?用來幫你全局相關(guān)的功能校驗(yàn)

django默認(rèn)有7個(gè)中間件,但是django暴露給用戶可以自定義中間件并且里面可以寫五種方法?

?

中間件的使用(5個(gè)固定的方法)

  process_request:請(qǐng)求來的時(shí)候從上往下依次執(zhí)行每一個(gè)中間件里面的process_request方法(如果沒有直接通過)

process_request(self,request)

?

  

  process_response:響應(yīng)走的時(shí)候會(huì)從下往上依次執(zhí)行每一個(gè)中間件里面的process_response方法(如果沒有直接通過)

process_response(self,request,response)return response

?

  

  

  process_view:路由匹配成功執(zhí)行視圖之前自動(dòng)觸發(fā)(從上往下依次執(zhí)行)

process_view(self, request, view_func, view_args, view_kwargs)

?

  

  process_exception:當(dāng)視圖函數(shù)報(bào)錯(cuò)了,自動(dòng)觸發(fā)(從下往上依次執(zhí)行)

process_exception(self,request,exception)

?

  process_template_response:視圖函數(shù)返回的對(duì)象有一個(gè)render()方法(或者表名對(duì)象是一個(gè)TemplateResponse對(duì)象或等價(jià)方法)(從上往下依次執(zhí)行)

process_template_response(self,request,response)

return response

  

?

完整的流程圖

?

?

?自定義中間件

  新建一個(gè)任意名字的文件夾,里面新建一個(gè)任意名字py文件

from django.utils.deprecation import MiddlewareMixin

?

?

?

?

class MyMiddleware(MiddlewareMixi):def process_request(self,request):print(''我是第一個(gè)自定義中間件里面的process_request方法')#return HttpResponse('heieheihei')def process_response(self,request,response):print('我是第一個(gè)自定義中間件里面的process_response方法')return response #必須將response形參接收的數(shù)據(jù)返回,不然直接報(bào)錯(cuò)def process_view(self,request,view_func,view_args,view_kwargs):print('我是第一個(gè)自定義中間件里面的process_view方法')print(view_func.__name__,view_func)def process_exception(self,request,exception):print('我是第一個(gè)自定義中間件里面的process_exception方法')print(exception)def process_template_response(self,request,response):print('我是第一個(gè)自定義中間件里面的process_template_response方法')return response

?

?

?自定義完之后再項(xiàng)目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   應(yīng)用.文件夾.自定義py文件.自定義中間件類名# 'app01.mymiddleware.mdzz.MyMiddleware1' #自定義中間件2 ]

?

?

?

csrf(跨站請(qǐng)求偽造)

由來:釣魚網(wǎng)站 拿到銀行轉(zhuǎn)賬的路徑,做一個(gè)跟銀行一模一樣的頁面,向銀行轉(zhuǎn)賬接口提交數(shù)據(jù),當(dāng)用戶在釣魚網(wǎng)站輸入對(duì)方賬戶名和轉(zhuǎn)賬金額之后,點(diǎn)擊發(fā)送,其實(shí)內(nèi)部是將對(duì)方賬戶換成了釣魚網(wǎng)站的造假人員的賬戶。造成你轉(zhuǎn)賬轉(zhuǎn)錯(cuò)賬戶的情況

<!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>正經(jīng)的網(wǎng)站</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> 正常頁面

?

釣魚網(wǎng)站提交連接也是銀行的轉(zhuǎn)賬接口

<!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>釣魚網(wǎng)站</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> 釣魚頁面

?

?

如何區(qū)分釣魚網(wǎng)站和正經(jīng)網(wǎng)站?在正經(jīng)網(wǎng)站返回頁面的時(shí)候,在form表單中偷偷塞一個(gè)特殊的字符串,后端記下該頁面對(duì)應(yīng)的字符串的值,等用戶發(fā)post請(qǐng)求來的時(shí)候,我先去校驗(yàn)特殊的字符串是否匹配

如何去寫這個(gè)特殊的字符串?

  模板語法有一個(gè)固定的寫法? ?必須寫在form表單內(nèi)

{% csrf_token %}

?

表單中偷偷塞的特殊的字符串

{% csrf_token %} <input type='hidden' name='csrfmiddlewaretoke' value='"2vzoo1lmSWgLTdI2rBQ4PTptJQKRQTRwnqeWRGcpdAQGagRp8yKg8RX2PdkF4aqh">Ps:value是動(dòng)態(tài)生成的,每一次刷新都不一樣

?

?

ajax中如何設(shè)置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導(dǎo)入

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

?

?

csrf 裝飾FBV

不校驗(yàn)csrf

@csrf_exempt def index1(request):return HttpResponse('ok')

?

校驗(yàn)csrf

@csrf_protect def index2(request):return HttpResonse('ok')

?

?

csrf裝飾給CBV?

先導(dǎo)入裝飾器語法

from django.utils.decorators import method_decorator

?

校驗(yàn)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')

?

不校驗(yàn)csrf  (只有兩種 每種都是全都不校驗(yàn))

@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)

          其實(shí)都是給dispatch加

?

Auth認(rèn)證模塊

執(zhí)行數(shù)據(jù)庫(kù)遷移的那兩命令式,即使我們沒有建表,django也會(huì)創(chuàng)建好多張表 auth_user表存放的用戶相關(guān)的數(shù)據(jù)

?

auth_user表記錄的添加

  創(chuàng)建超級(jí)用戶(不可手動(dòng)插入,因?yàn)槊艽a是加密的)

    可以使用命令行createsuperuser  會(huì)讓你輸入用戶名和密碼 但是都是明文輸入

  簡(jiǎn)單使用auth認(rèn)證  auth.authenticate(校驗(yàn)條件)

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 驗(yàn)證if user_obj:#設(shè)置用戶狀態(tài)#request.session['name'] = 'jason'auth.login(request,user_obj) #一旦記錄了 ,可以在任意的地方通過request.user獲取到當(dāng)前登錄對(duì)象return HttpResponse('ok')return render(request,'auth_login.html')

?

只要登錄成功執(zhí)行了auth.login(request,user_obj)

  之后在其他任意的視圖函數(shù)中都通過request.user獲取當(dāng)前登錄用戶對(duì)象

如果沒有執(zhí)行auth.login??  

  request.user打印出來的是匿名用戶

如何判斷request.user用戶是否通過auth.login登錄呢?  

  request.user.is_authenticated()

?為何auth.login之后,其他視圖函數(shù)中就可以通過request.user拿到當(dāng)前登錄對(duì)象呢?

  其實(shí)就是把用戶信息放到django_session表

?

注銷  auth.logout(request)

def auth_logout(request):auth.logout(request) #等價(jià)于request.session.flush()return HttpResponse('ok')

?

?

需要找到這張表

from django.contrib.auth.models import User

?

?注冊(cè)  User.objects.create_user 普通用戶 User.objectes.create_superuser  超級(jí)用戶

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)#校驗(yàn)用戶if user_obj:return HttpResponse('當(dāng)前用戶已存在')#User.objectes.create(username=username,password=password) 不能再用create創(chuàng)建#User.objects.create_user(username=username,password=password) #創(chuàng)建普通用戶User.objects.create_superuser(username=username,password=password,email='123@163.com') #創(chuàng)建超級(jí)用戶return render(request,'auth_register.html')

?

?

?更改密碼?  request.user.check_password('密碼') 校驗(yàn)密碼   request.user.set_password('新密碼') 設(shè)置新的密碼  request.user.save()  保存

def auth_password(request):print(request.user.password) #密文is_res = request.user.check_password('jason123') #校驗(yàn)密碼是否一致if is_res:request.user.set_password('666') #設(shè)置新密碼request.user.save() #修改密碼必須save保存 不然無效return HttpResponse('ok')

?

?

?裝飾器校驗(yàn)是否登錄及跳轉(zhuǎn)

?auth裝飾器

from django.contrib.auth.decorators import login_required

?

?被裝飾函數(shù)

@login_required(login_url='/login/',redirect_field_name = 'old') #沒登錄會(huì)跳轉(zhuǎn)login頁面,并且后面會(huì)拼接上你上一次想訪問的頁面路徑/login/?next=/你想訪問的路徑/ 可以通過參數(shù)修改next鍵名 def auth_home(request):return HttpResponse('home必須登錄才能訪問')

?

  如果我所有視圖函數(shù)都需要裝飾并跳轉(zhuǎn)到login頁面,那么我要寫好多份 為了一勞永逸

#可以在項(xiàng)目配置文件中指定auth校驗(yàn)登錄不合法統(tǒng)一跳轉(zhuǎn)到某一個(gè)路徑 LOGIN_URL = '/login/' #全局配置

?

?

自定義模型表引用auth功能

如何擴(kuò)張auth_user表?

  一對(duì)一關(guān)聯(lián)(不推薦)

from django.contrib.auth.model import Userclass UserDetail(models.Model):phone = models.CharField(max_length=11)user = models.OnoToOneField(to=User)  #User表在之前創(chuàng)建了 所以可以直接寫to=User

?

?

  面向?qū)ο蟮睦^承

    導(dǎo)入語法

from django.contrilb.auth.models import User,AbstractUser

?

?

class UserInfo(AbstractUser):phone = models.CharField(max_length=32)avatar = models.CharField(max_length=32)

?

?

告訴django不在使用默認(rèn)的auth_user,而使用我們自己定義的表

  語法:AUTH_USER_MODEL= ‘a(chǎn)pp名.models里面對(duì)相應(yīng)的模型表名’

在項(xiàng)目settings.py文件中配置

AUTH_USER_MODEL= 'app01.UserInfo'

?

?

自定義認(rèn)證系統(tǒng)默認(rèn)使用的數(shù)據(jù)表之后,我們我們就可以像使用默認(rèn)的auth_user表那樣使用我們的UserInfo表了

庫(kù)里面也沒有auth_user表了,原來auth表的操作方法,現(xiàn)在全部用自定義的表均可實(shí)現(xiàn)

?

轉(zhuǎn)載于:https://www.cnblogs.com/lakei/p/11048141.html

總結(jié)

以上是生活随笔為你收集整理的django CBV装饰器 自定义django中间件 csrf跨站请求伪造 auth认证模块的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。