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


 

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(內部循環....)

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM