Django REST framework:Authentication與Permissions

一、概念

Authentication即驗(yàn)證,Permissions即權(quán)限。

Authentication驗(yàn)證是將傳入請(qǐng)求與一組標(biāo)識(shí)憑據(jù)(例如請(qǐng)求來自的用戶或用于簽名的令牌)相關(guān)聯(lián)的機(jī)制。然后,Permissions權(quán)限決定了是否應(yīng)該授予或拒絕訪問請(qǐng)求。

這里一定要注意,只配置了Authentication,接口依然是可以訪問的。決定接口是否能夠訪問需要與Permissions一起配置。

二、Authentication

1、設(shè)置驗(yàn)證方案的3種方式:

(1)在settings中設(shè)置全局默認(rèn)身份驗(yàn)證方案DEFAULT_AUTHENTICATION_CLASSES:

(2)使用裝飾器,在基于函數(shù)的視圖上設(shè)置身份驗(yàn)證方案:

(3)使用APIView基于類的視圖在每個(gè)視圖或每個(gè)視圖集的基礎(chǔ)上設(shè)置身份驗(yàn)證方案:

2、身份認(rèn)證類

(1)基本認(rèn)證:BasicAuthentication

(2)會(huì)話認(rèn)證:SessionAuthentication

(3)令牌認(rèn)證:TokenAuthentication

首先,在APP中增加rest_framework.authtoken,如圖:

第二,執(zhí)行命令python manage.py migrate同步數(shù)據(jù)庫表,auth_user表是django框架生成的用戶表,接下來就使用這個(gè)表來保存用戶的信息;authtoken_token表是和用戶登錄認(rèn)證相關(guān)的數(shù)據(jù)表,用來存放用戶token。

第三,我們創(chuàng)建一個(gè)用戶,用于后期的登錄測(cè)試,執(zhí)行命令:python manage.py createsuperuser,創(chuàng)建成功后auth_user表就有了剛剛創(chuàng)建的數(shù)據(jù)。

接下來,我們來實(shí)現(xiàn)這個(gè)登錄接口,編寫views.py:

配置urls.py:

大家自行用接口測(cè)試工具提交post請(qǐng)求到登錄接口,我這邊就使用了DRF自帶的界面操作:

按照接口定義返回了token

因?yàn)槭鞘状蔚卿?,所以?huì)為該用戶創(chuàng)建token,即authtoken_token會(huì)產(chǎn)生一條記錄:

到這里就完成了登錄認(rèn)證,大家可以用接口測(cè)試工具測(cè)試,如果請(qǐng)求頭中不包含該token,那么無法獲取到數(shù)據(jù):

headers中不包含token

如果請(qǐng)求頭中包含token,以字符串文字“Token”為前綴,用空格分隔兩個(gè)字符串。例如:請(qǐng)求頭的格式:"Authorization":"Token XXXXXXXXXXXXXXXXXXXXXXXX"

(4)第三方包DRF-JWT

JWT:json web tokens,采用json格式在web上傳輸?shù)恼J(rèn)證字符串。

DRF中對(duì)應(yīng)的JWT包為:django-rest-framework-jwt,安裝pip install djangorestframework-jwt,增加認(rèn)證配置:

在項(xiàng)目的urls.py中配置:

編寫views.py:

測(cè)試一下,成功:

前端的其他請(qǐng)求,需要在請(qǐng)求頭中加入token,格式如下:"Authorization":"JWT <token>",如果希望token的前綴不要是JWT,例如是Bearer,可在settings中配置JWT_AUTH,如:

注意:由于drf-jwt的登錄驗(yàn)證默認(rèn)只支持使用username。

三、Permissions

權(quán)限決定了是否應(yīng)該授予或拒絕訪問請(qǐng)求。

權(quán)限檢查總是在視圖的最開始運(yùn)行,在任何其他代碼被允許繼續(xù)之前。

權(quán)限檢查通常使用request.user和request.auth屬性中的身份驗(yàn)證信息來確定是否應(yīng)允許傳入請(qǐng)求。

1、設(shè)置權(quán)限方案的3種方式

與Authentication設(shè)置一致。

2、權(quán)限類型

IsAuthenticated:最簡(jiǎn)單的權(quán)限樣式,允許任何經(jīng)過身份驗(yàn)證的用戶訪問,并拒絕任何未經(jīng)身份驗(yàn)證的用戶訪問。

IsAuthenticatedOrReadOnly:一種稍微不那么嚴(yán)格的權(quán)限樣式,允許對(duì)經(jīng)過身份驗(yàn)證的用戶進(jìn)行完全訪問,但允許對(duì)未經(jīng)身份驗(yàn)證的用戶進(jìn)行只讀訪問。

AllowAny:允許無限制訪問。

IsAdminUser:只允許管理員用戶訪問。

3、自定義權(quán)限

要實(shí)現(xiàn)自定義權(quán)限,需要覆蓋BasePermission,并實(shí)現(xiàn)以下任一方法或兩者:

(1).has_permission(self, request, view)

(2).has_object_permission(self, request, view, obj)

(3)True表示條件通過,F(xiàn)alse表示條件不通過。

四、自定義認(rèn)證與自定義權(quán)限的使用

由于drf-jwt是基于django自帶的認(rèn)證系統(tǒng)(庫中的auth_user表)來實(shí)現(xiàn)的,我自己的庫的Users表是沒有username字段的,且登錄驗(yàn)證使用字段user_no和password,所以使用pyjwt實(shí)現(xiàn)了令牌認(rèn)證,如圖,根據(jù)user_no與password生成token:

views.py中登錄的token生成使用get_jwt_token方法:

生成了token之后,怎么樣才能讓其他接口都走這個(gè)JWT的驗(yàn)證機(jī)制呢?

1、自定義認(rèn)證

參照官方文檔:要實(shí)現(xiàn)自定義身份驗(yàn)證方案,需繼承BaseAuthentication類,并使用authenticate(self, request)方法,返回user, auth。如圖,新建一個(gè)myauth.py文件,這里寫的比較簡(jiǎn)單,還可以加上驗(yàn)證token是否過期等:

配置自定義認(rèn)證,我這里使用的是全局配置的方式,在settings中配置:

2、自定義權(quán)限

用戶認(rèn)證完成后,需要配置權(quán)限,權(quán)限決定了請(qǐng)求是否能夠通過,要求任何經(jīng)過身份驗(yàn)證的用戶都訪問,但是拒絕任何未經(jīng)身份驗(yàn)證的用戶訪問。由于Users表是使用我自己創(chuàng)建的表,使用默認(rèn)的權(quán)限('rest_framework.permissions.IsAuthenticated')會(huì)報(bào)錯(cuò):not request.user.is_authenticated,所以使用自定義的權(quán)限。

新建一個(gè)myperm.py文件,寫的比較簡(jiǎn)單:

配置自定義權(quán)限,我這里也是使用的是全局配置的方式,在settings中配置:

以上,就完成了一個(gè)項(xiàng)目最基礎(chǔ)的驗(yàn)證和權(quán)限。

可以使用接口測(cè)試工具測(cè)試一下,先POST登錄接口,獲取JWT,在使用該用戶的JWT訪問其他接口,就可以獲取到數(shù)據(jù)。

如果請(qǐng)求頭中沒有攜帶JWT或者JWT錯(cuò)誤,是無法獲取到數(shù)據(jù)的。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容