目錄
一 什么是restful架構
二 Django REST framework簡介
三 Django REST framework原理
四 Django REST framework源碼流程
五 Django REST framework實現用戶登錄
一 什么是restful架構
1、起源
REST即表述性狀態傳遞(英文:Representational State Transfer,簡稱REST)是Roy Fielding博士在2000年他的博士論文中提出來的一種軟件架構風格。它是一種針對網絡應用的設計和開發方式,可以降低開發的復雜性,提高系統的可伸縮性。
目前在三種主流的Web服務實現方案中,因為REST模式的Web服務與復雜的SOAP和XML-RPC對比來講明顯的更加簡潔,越來越多的web服務開始采用REST風格設計和實現。例如,Amazon.com提供接近REST風格的Web服務進行圖書查找;雅虎提供的Web服務也是REST風格的
2、框架組成
根據rest的論文,我們大致可以把restful架構分成以下幾個部分
1. 資源
資源就是網絡中的具體信息。比如說招聘信息、美女圖片、NBA賽事、股票信息、歌曲等等。每一種具體資源都可以用一個URI(統一資源定位符)指向它。如果想要獲取這些資源,則直接訪問它的URI就可以。
有很多公共的URI,例如阿里雲的api市場就提供了很多種的api,每種api代替了具體的資源,每種資源你都可以通過訪問api獲取到。
例如訪問下面圖片中的api地址,就可以獲取到滬深港股票歷史行情數據
2. 表現方式
在資源里我們提到了阿里雲提供了很多api,api獲取了是一些靜態資源,而表現方式就會為了處理獲取到的這些資源以什么樣的形式展示給訪問者。
現在常用的方式有比如,txt格式、HTML格式、XML格式、JSON格式表現,甚至可以采用二進制格式;圖片可以用JPG格式表現,也可以用PNG格式表現。
從上圖可以看到,api的表現形式(也就是返回數據格式)為json格式。
3. 狀態
狀態定義了做資源的操作方式。這些操作方式全部定義在http協議里面,而不再api上表現。客戶端通過四個HTTP動詞,對服務器端資源進行操作
具體操作:
- GET(SELECT):從服務器取出資源(一項或多項)。
- POST(CREATE):在服務器新建一個資源。
- PUT(UPDATE):在服務器更新資源(客戶端提供完整資源數據)。
- PATCH(UPDATE):在服務器更新資源(客戶端提供需要修改的資源數據)。
- DELETE(DELETE):從服務器刪除資源。
3、認證機制
我們知道,客戶端通過api可以訪問到資源,但我們還需要對訪問者進行驗證,以用來判斷該用戶的訪問權限。
常用的認證機制包括 session auth(即通過用戶名密碼登錄),basic auth,token auth和OAuth,服務開發中常用的認證機制為后三者。
這里主要介紹一下OAuth。
1. OAuth介紹
OAuth(開放授權)是一個開放的授權標准,允許用戶讓第三方應用訪問該用戶在某一web服務上存儲的私密的資源(如照片,視頻,聯系人列表),而無需將用戶名和密碼提供給第三方應用。
OAuth允許用戶提供一個令牌,而不是用戶名和密碼來訪問他們存放在特定服務提供者的數據。每一個令牌授權一個特定的第三方系統(例如,視頻編輯網站)在特定的時段(例如,接下來的2小時內)內訪問特定的資源(例如僅僅是某一相冊中的視頻)。這樣,OAuth讓用戶可以授權第三方網站訪問他們存儲在另外服務提供者的某些特定信息,而非所有內容。
正是由於OAUTH的嚴謹性和安全性,現在OAUTH已成為RESTful架構風格中最常用的認證機制,和RESTful架構風格一起,成為企業級服務的標配。
目前OAuth已經從OAuth1.0發展到OAuth2.0,但這二者並非平滑過渡升級,OAuth2.0在保證安全性的前提下大大減少了客戶端開發的復雜性。
二 Django REST framework簡介
Django REST framework是一個基於Django實現的一個restful框架,一個十分強大切靈活的工具包,用以構建Web APIs。
Djando REST framework的優點:
- 在線可視的API
- 驗證策略涵蓋了OAuth1和OAuth2
- 同時支持ORM和非ORM數據源的序列化
- 支持基於類的視圖
安裝與部署環境
使用pip安裝框架以及所有依賴包
pip install djangorestframework
pip install markdown # 可以更好的支持可瀏覽的API
pip install django-filter # 支持過濾
還可以使用clone安裝
git clone git@github.com:encode/django-rest-framework.git
安裝完之后需要在項目的配置文件的app里面注冊rest_framework,因為有些地方會用到rest_framework這個app里面的數據,例如返回數據的模板
INSTALLED_APPS= (
...
'rest_framework',
)
三 Django REST framework簡單流程
首先我們看一個通過Django REST framework實現的一個api的簡單實例
# views.py 首先寫視圖函數
from rest_framework.views import APIView
from rest_framework.response import Response
class TestView(APIView): # CBV模式的視圖函數
def get(self, request, *args, **kwargs):
# 定義get方法
# 在django-rest-framework中的request被重新封裝了,后續分析源碼的時候會有具體體現
return Response('測試api') # rest-framework的模板對數據進行渲染
# urls.py 定義路由
from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
url(r'^user/', views.TestView.as_view())
]
啟動項目,訪問api:
原理分析:
- rest_framework重寫了一個APIView的類,這個類是之前django中的view類的派生類,在寫CBV的視圖函數是,讓視圖函數繼承了rest-framework這個APIView類
- 在視圖函數中寫具體方法,例如get,port,put,delete,可以使用rest_framework的Response對返回數據進行渲染
- 在url的寫法和Django是一樣的
- 通過對http://127.0.0.1:8000/user/ 的訪問,可以得到如圖顯示的數據
四 Django REST framework源碼流程
在第三節我們分析了一個簡單的api實現過程,現在我們主要去分析rest_framework內部對這個url的具體實現過程。
-
首先我們訪問http://127.0.0.1:8000/user/ 根據urls.py中的配置,執行views.TestView.as_view()函數
-
as_view方法是被定義在rest_framework/views.py里面的一個靜態方法,所以可以通過類名直接調用。
-
父類的as_view方法是定義在django/views/generic/base.py里面的View類中的方法。在這個方法中最終會執行cls.dispatch,在第一步中我們知道cls是<class 'app01.views.TestView'>
-
dispatch是定義在TestView繼承的父類APIView(rest_framework/views.py)里面的方法。在這個方法里面,首先通過
request = self.initialize_request(request, *args, **kwargs)
這條語句重新封裝了request對象 -
initialize_request是APIView類里面的一個方法,重新封裝了request對象,增加了一些屬性信息
-
認證信息。主要通過APIView類中的get_authenticators(rest_framework/views.py)方法獲取,這個方法會返回一個所有認證對象的列表
在全局定義的authentication_classes = api_settings.DEFAULT_AUTHENTICATION_CLASSES
-
默認的認證配置信息是在rest_framework/settings.py文件中定義的
-
在rest_framework/authentication.py中定義了幾種認證類型,一般情況我們需要自定義認證類,也可以使用django-oauth-toolkit組件進行認證。
-
dispatch中的initialize_request方法執行完成之后,還有執行一個重要方法是self.initial(request, *args, **kwargs),這個方法也是APIView類里的。在這個方法里面初始化
被重新封裝的request對象
實現功能:- 版本處理
- 用戶認證
- 權限
- 訪問頻率限制
-
執行APIView里面的perform_authentication方法,該方法返回request.user,則會調用<rest_framework.request.Request object at 0x10e80deb8>里面的user方法。在user方法里面最終調用了Request類里面的_authenticate方法
-
執行rest_framework.request.Request類中的_authenticate方法,這個方法會遍歷認證類,並根據認證結果給self.user, self.auth賦值。由於user,和auth都有property屬性,
所以給賦值的時候先在先執行setter方法
-
dispatch中的initial方法執行完之后,會繼續判斷request.method並執行method相應的method.
-
執行TestView中定義的get方法,返回數據