rest_framework-00-規範-APIview源碼解析-認證
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(rapi接口方式‘^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(‘刪除訂單‘)
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源碼解析-認證