第一節: 基本介紹django
1. REST框架中, 因爲是先後端分離, 因此已是跨站點訪問, 因此csrf認證也就不必作了. segmentfault
框架中的 BasicAuthentication 和 SessionAuthentication 這兩個類實際上也沒幹啥事, 仍然是利用django自己的 SessionMiddleware 和 AuthenticationMiddleware 這兩個中間件後端
那麼, REST中的認證有什麼特別的地方嗎? 有! 在於其本身的 TokenAuthentication 類api
2. 首先是註冊app瀏覽器
INSTALLED_APPS = [ ... 'rest_framework.authtoken' ]
3. 使用 makemigrations 和 migrate 生成 token 表, 這個表只有3個字段, user_id 外鍵到咱們的userprofile表app
3.實際上 token 和 user 是一一對應的, 但token不會自動建立, 因此須要單獨的配置, 配置以下,框架
每次用戶註冊的時候, 咱們都應該調用這個函數前後端分離
用戶登陸的時候, 也會自動生成tokenide
from rest_framework.authtoken.models import Token token = Token.objects.create(user=...) print(token.key)
4.另外, 瀏覽器端的用戶認證, 應該帶上如下頭信息函數
Authorization: Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b #中間有空格
5.最後是url的配置
from rest_framework.authtoken import views urlpatterns += [ url(r'^api-token-auth/', views.obtain_auth_token) ]
6.配置好後, 使用google瀏覽器的SERVISTATE插件來進行post測試
(以前沒加X-CSRFTOKEN, 參考這個才弄成了 https://segmentfault.com/a/1190000016493704 和 https://segmentfault.com/a/1190000000764598 )
7.額外的, 能夠發現, drf的authtoken在檢查到用戶發起請求時, 但用戶若是沒有token, 則會自動給用戶生成token
第二節: 攜帶Token去訪問
1. 有了前面的分析, 咱們已經知道一個用戶有一個Token, 而drf因爲先後端分離的特性, 因此使用其本身的獨特的token驗證機制, 只要在訪問的時候帶上Token, 服務端就能夠肯定用戶是誰, 接下來去驗證一下
咱們在ListModelMixin裏面的queryset這裏打斷點, 並使用get發送一個請求
2. 從上面的結果來看, 對於普通請求, 服務端沒有用戶信息, 接下來去測試帶上Token的值結果會是怎樣
3. django是如何將user封裝進來的,這個就須要對django的流程有所瞭解了, 轉載 http://www.projectsedu.com/archives/ django從請求到返回都經歷了什麼
另外, REST是如何給用戶生成Token的, 看下面的源碼
urls中的views.obtain_auth_token.ObtainAuthToken ... def post(self, request, *args, **kwargs): serializer = self.serializer_class(data=request.data, context={'request': request}) serializer.is_valid(raise_exception=True) user = serializer.validated_data['user'] token, created = Token.objects.get_or_create(user=user) return Response({'token': token.key})
重點:
4. 如今有這麼一種狀況, 假設全局當中只有Goodslist接口是一個須要登錄後才能訪問的接口, 那麼咱們前面的設置又是一個全局的Token檢查, 怎麼樣才能達到對某一個接口實時單獨的Token認證呢?
方法就是把Token認證移動到對應的View函數內部, 同時刪掉全局Token認證
goods.view.py from rest_framework.authentication import TokenAuthentication class GoodsListViewSet(mixins.ListModelMixin, viewsets.GenericViewSet): ... authentication_classes = [TokenAuthentication,] # 對goodslist接口單獨設置Token認證 ...
----- 君子處其實,不處其華;治其內,不治其外 張居正 ------