1. 程式人生 > >rest_framework-01-認證(用戶登錄)-內置認證

rest_framework-01-認證(用戶登錄)-內置認證

函數 如何 ews user self. 沒有 幫我 body 技術

rest_framework-01-認證(用戶登錄)-內置認證

如果我們寫API有人能訪問,有人不能訪問,則需要些認證。

如何知道該用戶是否已登入?

如果用戶登入成功,則給用戶一個隨機字符串,去訪問另一個頁面。

以前寫session的時候,都是把session寫cookie裏面。

那現在我們可以把隨機字符串通過返回值的方式給用戶。

後端通過查看用戶的url判斷用戶有沒有token值且這個字符串是否正確也要判斷。有則已登入,可以訪問;沒有則跳回登入頁面。

用戶登入

1.有些api需要用戶登入才能訪問,有些api不需要用戶登入就能訪問。

1.api(app應用) > models.py: 表

技術分享圖片

2.創建表數據:用戶表

技術分享圖片

3.urls.py

技術分享圖片

4.views.py:用戶登入只有post請求!!!

技術分享圖片

5.token用md5加密,並保存或更新到數據庫中。

技術分享圖片

技術分享圖片

6.post請求,運行結果:

技術分享圖片

7.token就保存到數據庫了。

技術分享圖片

8.token生成成功後,就將新的token返回給用戶。有異常則返回異常。API寫完了。

技術分享圖片

views.py:API寫完了。

技術分享圖片

運行結果:

技術分享圖片

小結:解決: a. 創建兩張表b. 用戶登錄(返回token並保存到數據庫)。

認證

用戶所有訂單api

1.訂單url

技術分享圖片

2.views.py訂單視圖

假設這是所有訂單數據

技術分享圖片

技術分享圖片

3.運行結果:get請求

技術分享圖片

4.如果這個訂單只有登入成功的時候才可以看,你會怎麽解決???

技術分享圖片

運行結果:

技術分享圖片

rest_framework認證

5.這段代碼假設post請求也要認證,如果再復制一遍就會很冗余。django已經幫我們封裝好了,不用自己寫。

技術分享圖片

6.自定義一個認證類,自己寫認證規則。

技術分享圖片

7.認證源碼:

技術分享圖片

8.自己定義認證規則,認證失敗則返回一個異常。

技術分享圖片

技術分享圖片

9.註意:必須再寫一個方法,否則還會報錯。

引入該模塊, 加上該方法:先為空。

技術分享圖片

查看該模塊源碼:

技術分享圖片

加上該方法:先為空。

技術分享圖片

註釋一下代碼:

技術分享圖片

運行結果:

技術分享圖片

用戶信息api

1.假設用戶信息api也要認證,(登入後才能訪問),怎麽辦呢?

自定義的一個認證寫完了之後,api視圖加上就好了。

技術分享圖片

2.如果有成千上萬個api都需要認證怎麽辦呢??? 接下來全局認證。(不需要每一個視圖都自己加上以上代碼)全局配置settings.py。

認證源碼流程圖:

技術分享圖片

源碼配置:

1.dispatch

技術分享圖片

2.封裝Request

技術分享圖片

3.for循環認證列表

技術分享圖片

4.默認去全局的配置文件讀

技術分享圖片

5.如果自己請求函數裏面設置了,就用自己的。沒設置就用配置文件的。

技術分享圖片

6.將認證寫在配置文件中,不用局部的。

源碼:

api_settings表示去配置文件中讀。

技術分享圖片

讀 REST_FRAMEWORK 這個key

技術分享圖片

7.setting.py

技術分享圖片

8.將認證相關的東西都寫在一個文件中。再引入該文件。

技術分享圖片

settings.py

REST_FRAMEWORK = {
    # 全局使用的認證類
    "DEFAULT_AUTHENTICATION_CLASSES":[api.utils.auth.FrstAuthtication,api.utils.auth.Authtication],
}

views.py:視圖文件中只有視圖相關的類。

技術分享圖片

9.列表裏填你自己寫的認證類的路徑。 view.py裏的所有類都不用加了,默認用session全局的認證。

技術分享圖片

10.登入不需要認證信息。全局認證,個別不需要認證。

空列表就行

技術分享圖片

11.運行結果:

訂單接口:

技術分享圖片

登入接口:

技術分享圖片

訂單接口:

技術分享圖片

request封裝完了(認證配置),接下來繼續看源碼。

0.request封裝

技術分享圖片

1.讀取全局認證配置

技術分享圖片

2.進行認證

技術分享圖片

3.initial > 實現認證self.perform_authentication(request)

技術分享圖片

4.user

技術分享圖片

5.獲取認證對象,進行下一步步的認證

技術分享圖片

往下走

技術分享圖片

技術分享圖片

6.如果是匿名用戶,默認叫什麽

setting.py

技術分享圖片

views.py

技術分享圖片

urls.py

技術分享圖片

運行結果:

技術分享圖片

7.源碼設置默認用戶名:

技術分享圖片

8.設置匿名用戶名

"UNAUTHENTICATED_USER":lambda :"匿名用戶"
匿名函數沒有參數,直接返回字符串

技術分享圖片

url請求:

技術分享圖片

運行結果:

技術分享圖片

9.setting.py:

技術分享圖片

技術分享圖片

內置認證

1.django內置的認證在哪呢?引入BaseAuthentication

from rest_framework.authentication import BaseAuthentication

技術分享圖片

BaseAuthentication源碼:

1.

技術分享圖片

2.BaseAuthentication 下有兩個方法。

技術分享圖片

3.推薦繼承BaseAuthentication。更規範。

技術分享圖片

代碼:

技術分享圖片
from rest_framework import exceptions
from api import models
from rest_framework.authentication import BaseAuthentication

# 用戶認證
class FrstAuthtication(BaseAuthentication):
    def authenticate(self,request):
        pass
    def authenticate_header(self, request):
        pass

class Authtication(BaseAuthentication):
    def authenticate(self,request):
        token = request._request.GET.get(token)
        token_obj = models.UserToken.objects.filter(token=token).first()
        if not token_obj:   #  未登入或者是錯誤的token
            raise exceptions.AuthenticationFailed(用戶認證失敗!)
        # 認證成功。在rest_framework內部會將整個兩個字段賦值給request,以供後續操作使用。
        return (token_obj.user,token_obj)

    def authenticate_header(self, request):
        pass
auth.py 認證文件

接下來繼續走源碼: BasicAuthentication 基於留言器認證

技術分享圖片

1.往下走,復制源碼

技術分享圖片

2.設置請求頭的返回值為api

技術分享圖片

settings.py

技術分享圖片

運行結果:

技術分享圖片

3.views.py: 引入BasicAuthentication

技術分享圖片

4.運行結果:

技術分享圖片

5.看源碼

技術分享圖片

6.改源碼,先註釋一下2行代碼

技術分享圖片

不註釋表示允許用戶為匿名用戶。

技術分享圖片

7.運行結果:瀏覽器會對用戶名和密碼加密放到url上,然後發給服務端,進行驗證。

技術分享圖片

8.還原代碼:

技術分享圖片

BasicAuthentication原理:

技術分享圖片

小結:

今日內容:
    1. 認證
        a. 問題1:有些API需要用戶登錄成功之後,才能訪問;有些無需登錄就能訪問。
        b. 基本使用認證組件
            解決:
                a. 創建兩張表
                b. 用戶登錄(返回token並保存到數據庫)
        c. 認證流程原理
            - 見圖示
        
        d. 再看一遍源碼
            1. 局部視圖使用&全局使用
            2. 匿名是request.user = None
            
        e. 內置認證類
            1. 認證類,必須繼承:from rest_framework.authentication import BaseAuthentication
            2. 其他認證類:BasicAuthentication
            
        梳理:
            1. 使用 
                - 創建類:繼承BaseAuthentication; 實現:authenticate方法
                - 返回值:3種返回值
                    - None,我不管了,下一認證來執行。
                    - raise exceptions.AuthenticationFailed(用戶認證失敗) # from rest_framework import exceptions
                    - (元素1,元素2)  # 元素1賦值給request.user; 元素2賦值給request.auth 
                    
                - 局部使用
                    from rest_framework.authentication import BaseAuthentication,BasicAuthentication
                    class UserInfoView(APIView):
                        """
                        訂單相關業務
                        """
                        authentication_classes = [BasicAuthentication,]
                        def get(self,request,*args,**kwargs):
                            print(request.user)
                            return HttpResponse(用戶信息)
                - 全局使用:
                    REST_FRAMEWORK = {
                        # 全局使用的認證類
                        "DEFAULT_AUTHENTICATION_CLASSES":[api.utils.auth.FirstAuthtication,api.utils.auth.Authtication, ],
                        # "UNAUTHENTICATED_USER":lambda :"匿名用戶"
                        "UNAUTHENTICATED_USER":None, # 匿名,request.user = None
                        "UNAUTHENTICATED_TOKEN":None,# 匿名,request.auth = None
                    }
            2. 源碼流程
                - dispatch
                    - 封裝request
                        - 獲取定義的認證類(全局/局部),通過列表生成時創建對象。
                    - initial
                        - perform_authentication
                            request.user(內部循環....)

rest_framework-01-認證(用戶登錄)-內置認證