1. 程式人生 > >rest_framework-00-規範-APIview源碼解析-認證

rest_framework-00-規範-APIview源碼解析-認證

head table 技術 resp 禁止 結果 itl ica lex

rest_framework-00-規範-APIview源碼解析-認證

規範

支付寶:

技術分享圖片

接口開發

訂單api----order

方式1:缺點:如果有10張表,則需要40個url.

urls.py

技術分享圖片

views.py

技術分享圖片

缺點:如果有10張表,則需要40個url. 接下來就出現了resrful 規範,比較簡潔

方式2:resrful 規範(建議) url簡潔了,只有一條。

1. 根據method不同做不同的操作,示例:基於FBV:

urls.py

技術分享圖片

views.py

技術分享圖片

2. 根據method不同做不同的操作,示例:基於CBV:

urls.py:

技術分享圖片

views.py:

技術分享圖片

settings.py

技術分享圖片

運行結果:

技術分享圖片

代碼:

技術分享圖片
        a. 接口開發
            
            urlpatterns = [
                # url(r‘^admin/‘, admin.site.urls),
                url(r^get_order/, views.get_order),
                url(r^add_order/, views.add_order),
                url(r^del_order/, views.del_order),
                url(r
^update_order/, views.update_order), ] def get_order(request): return HttpResponse(‘‘) def add_order(request): return HttpResponse(‘‘) def del_order(request): return HttpResponse(‘‘
) def update_order(request): return HttpResponse(‘‘) b. restful 規範(建議) 1. 根據method不同做不同的操作,示例: 基於FBV: urlpatterns = [ url(r^order/, views.order), ] def order(request): if request.method == GET: return HttpResponse(獲取訂單) elif request.method == POST: return HttpResponse(創建訂單) elif request.method == PUT: return HttpResponse(更新訂單) elif request.method == DELETE: return HttpResponse(刪除訂單) 基於CBV: urlpatterns = [ url(r^order/, views.OrderView.as_view()), ] class OrderView(View): def get(self,request,*args,**kwargs): return HttpResponse(獲取訂單) def post(self,request,*args,**kwargs): return HttpResponse(創建訂單) def put(self,request,*args,**kwargs): return HttpResponse(更新訂單) def delete(self,request,*args,**kwargs): return HttpResponse(刪除訂單)
api接口方式

2.django rest framework規範有哪些?

10個規則:

1.https 、2.域名、3.版本、4.名詞、method請求方式、過濾條件、狀態碼、錯誤值、返回結果、Hypermedia API鏈接
註意:推薦使用CBV

  • API與用戶的通信協議,總是使用HTTPs協議
  • 域名
    • https://api.example.com 盡量將API部署在專用域名(會存在跨域問題)
    • https://example.org/api/ API很簡單
  • 版本
    • URL,如:https://api.example.com/v1/
    • 請求頭 跨域時,引發發送多次請求
  • 路徑,視網絡上任何東西都是資源,均使用名詞表示(可復數)
    • https://api.example.com/v1/zoos
    • https://api.example.com/v1/animals
    • https://api.example.com/v1/employees
  • method
    • GET :從服務器取出資源(一項或多項)
    • POST :在服務器新建一個資源
    • PUT :在服務器更新資源(客戶端提供改變後的完整資源)
    • PATCH :在服務器更新資源(客戶端提供改變的屬性)
    • DELETE :從服務器刪除資源
  • 過濾,通過在url上傳參的形式傳遞搜索條件
    • https://api.example.com/v1/zoos?limit=10:指定返回記錄的數量
    • https://api.example.com/v1/zoos?offset=10:指定返回記錄的開始位置
    • https://api.example.com/v1/zoos?page=2&per_page=100:指定第幾頁,以及每頁的記錄數
    • https://api.example.com/v1/zoos?sortby=name&order=asc:指定返回結果按照哪個屬性排序,以及排序順序
    • https://api.example.com/v1/zoos?animal_type_id=1:指定篩選條件
  • 狀態碼
200 OK - [GET]:服務器成功返回用戶請求的數據,該操作是冪等的(Idempotent)。
201 CREATED - [POST/PUT/PATCH]:用戶新建或修改數據成功。
202 Accepted - [*]:表示一個請求已經進入後臺排隊(異步任務)
204 NO CONTENT - [DELETE]:用戶刪除數據成功。
400 INVALID REQUEST - [POST/PUT/PATCH]:用戶發出的請求有錯誤,服務器沒有進行新建或修改數據的操作,該操作是冪等的。
401 Unauthorized - [*]:表示用戶沒有權限(令牌、用戶名、密碼錯誤)。
403 Forbidden - [*] 表示用戶得到授權(與401錯誤相對),但是訪問是被禁止的。
404 NOT FOUND - [*]:用戶發出的請求針對的是不存在的記錄,服務器沒有進行操作,該操作是冪等的。
406 Not Acceptable - [GET]:用戶請求的格式不可得(比如用戶請求JSON格式,但是只有XML格式)。
410 Gone -[GET]:用戶請求的資源被永久刪除,且不會再得到的。
422 Unprocesable entity - [POST/PUT/PATCH] 當創建一個對象時,發生一個驗證錯誤。
500 INTERNAL SERVER ERROR - [*]:服務器發生錯誤,用戶將無法判斷發出的請求是否成功。

更多看這裏:http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html

  

def get(self,request,*args,**kwargs):
ret = {
‘code‘:1000,
‘msg‘:‘xxx‘
}
# return HttpResponse(json.dumps(ret))
return HttpResponse(json.dumps(ret), status=201)

  • 錯誤處理,狀態碼是4xx時,應返回錯誤信息,error當做key。
{
    error: "Invalid API key"
}

  • 返回結果,針對不同操作,服務器向用戶返回的結果應該符合以下規範。
GET /collection:返回資源對象的列表(數組)
GET /collection/resource:返回單個資源對象
POST /collection:返回新生成的資源對象
PUT /collection/resource:返回完整的資源對象
PATCH /collection/resource:返回完整的資源對象
DELETE /collection/resource:返回一個空文檔

  • Hypermedia API,RESTful API最好做到Hypermedia,即返回結果中提供鏈接,連向其他API方法,使得用戶不查文檔,也知道下一步應該做什麽。
{"link": {
  "rel":   "collection https://www.example.com/zoos",
  "href":  "https://api.example.com/zoos",
  "title": "List of zoos",
  "type":  "application/vnd.yourformat+json"
}}

 

django rest framework框架 

1.django rest framework框架的下載:
pip3 install djangorestframework

3.引出rest_framework

urls.py

技術分享圖片

views.py

技術分享圖片

2.APIview

技術分享圖片

APIView源碼:

1.APIView繼承了View

技術分享圖片

技術分享圖片原生view

2、APIView類裏面有dispatch方法

技術分享圖片

3、 APIView在原有的基礎上,多了很多功能。request:進行了加工,是一個新的對象。

技術分享圖片

4.請求封裝request = self.initialize_request(request, *args, **kwargs)(版本、認證、權限、節流、解析器)

技術分享圖片

5.認證

技術分享圖片

6.如果自己寫了用戶認證,就找自己的認證方法:

技術分享圖片

技術分享圖片

7.加註釋、initial

技術分享圖片

8.initial

技術分享圖片

9.認證

技術分享圖片

10.request是封裝後的對象了,所有user應該去APIView裏面找。

技術分享圖片

11._authenticate # 循環認證類的所有對象 [BasicAuthentication對象,]

技術分享圖片

.authenticate方法檢查你是否已登入。如果用戶沒有登入則報錯。

12.接下來自己定義一個認證方法:必須有authenticate方法:如果用戶沒有登入,則報錯。

技術分享圖片

運行結果:url沒有傳token值,則認證失敗

技術分享圖片

url傳了token,認證成功

技術分享圖片

13.認證流程加註釋

0.url.as_view -》 1.self.dispatch

self.dispatch

技術分享圖片

2.initial(版本、認證、權限、節流、解析器)

技術分享圖片

技術分享圖片

3.perform_authentication 實現認證

技術分享圖片

4. from rest_framework.request import Request 方便查詢user

技術分享圖片

技術分享圖片

技術分享圖片

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

技術分享圖片

認證流程:view -> dispach -> 封裝Request -> initial:(版本、認證、權限、節流、解析器)-> perform_authentication 實現認證 -user -> authenticate方法

如果認證成功有(token值),request.user則有值。

技術分享圖片

技術分享圖片

認證代碼:

        a. 認證 
            - 僅使用:
                    from django.views import View
                    from rest_framework.views import APIView
                    from rest_framework.authentication import BasicAuthentication
                    from rest_framework import exceptions
                    from rest_framework.request import Request

                    class MyAuthentication(object):
                        def authenticate(self,request):
                            token = request._request.GET.get(token)
                            # 獲取用戶名和密碼,去數據校驗
                            if not token:
                                raise exceptions.AuthenticationFailed(用戶認證失敗)
                            return ("alex",None)

                        def authenticate_header(self,val):
                            pass

                    class DogView(APIView):
                        authentication_classes = [MyAuthentication,]

                        def get(self,request,*args,**kwargs):
                            print(request)
                            print(request.user)
                            ret  = {
                                code:1000,
                                msg:xxx
                            }
                            return HttpResponse(json.dumps(ret),status=201)

                        def post(self,request,*args,**kwargs):
                            return HttpResponse(創建Dog)

                        def put(self,request,*args,**kwargs):
                            return HttpResponse(更新Dog)

                        def delete(self,request,*args,**kwargs):
                            return HttpResponse(刪除Dog)

rest_framework-00-規範-APIview源碼解析-認證