django rest-framework 4.REST的認證和權限

目前,咱們的API對誰能夠編輯或刪除代碼段沒有任何限制。咱們想要一些更先進的行爲,以確保:(這段話抄自官網)python

  • 代碼段始終與建立者相關聯。
  • 只有身份驗證的用戶能夠建立片斷。
  • 只有片斷的建立者能夠更新或刪除它。
  • 未經身份驗證的請求應具備徹底只讀訪問權限。

1、將信息添加至 model

使用官方例子在表中添加用戶字段,該字段用來判斷是否與登陸用戶有關係。django

owner = models.ForeignKey('auth.User', related_name='snippets', on_delete=models.CASCADE)
highlighted = models.TextField()

這裏的owner用戶關聯的爲django admin的認證用戶,該字段用與匹配登陸用戶是否有權限修改該數據(後面涉及到)。後端

2、爲用戶模型添加端點

爲 auth.User 表添加到api中,首先須要添加序列化。因爲snippets(這裏的smippets爲外鍵的related_name,默認爲"表名_set")在用戶模型上是反向關係,因此在使用ModelSerializer 類時它不會被默認包含,須要添加一個顯示的字段。api

# 用戶序列化函數  serializers.py
from django.contrib.auth.models import User

class UserSerializer(serializers.ModelSerializer):
    snippets = serializers.PrimaryKeyRelatedField(many=True, queryset=Snippet.objects.all())

    class Meta:
        model = User
        fields = ('id', 'username', 'snippets')

# 用戶視圖函數  views.py
from django.contrib.auth.models import User
from snippets.serializers import UserSerializer

class UserList(generics.ListAPIView):
    queryset = User.objects.all()
    serializer_class = UserSerializer


class UserDetail(generics.RetrieveAPIView):
    queryset = User.objects.all()
    serializer_class = UserSerializer
#  配置URL conf
url(r'^users/$', views.UserList.as_view()),
url(r'^users/(?P<pk>[0-9]+)/$', views.UserDetail.as_view()),
用戶模型添加api

3、snippets 和 user 關聯

關聯用戶經過重寫SnippetList 視圖類的 perform_create(),該方法修改實例保存的管理方式,並處理傳入請求或request中的任何信息。app

  SnippetList視圖類上,添加如下方法:(我的理解:使保存的數據用戶字段爲登陸用戶的信息)框架

def perform_create(self, serializer):
    serializer.save(owner=self.request.user)

4、更新serializer

snippets 和 user關聯後,在snippets中owner的信息默認爲id信息,更新序列化類(serializer)是owner顯示爲用戶名信息。ide

# 更新 SmippetSerializer 添加以下:
owner = serializers.ReadOnlyField(source='owner.username')

# 並確保 fields 中有owner字段。

  咱們添加的是無類型的 ReadOnlyField 類,與其餘類型的字段(CharField,BooleanField等)相比ReadOnlyField 老是隻讀的。若是設置爲ReadOnlyField 該字段則不用用於更新(可是參數仍是會傳遞到後端。),咱們也可使用CharField(read_only=Ture)來指定字段類型而且設置爲只讀字段。函數

5、爲視圖添加權限

  既然Snippet和user相關聯,咱們但願只有通過身份驗證的用戶才能建立,更新和刪除代碼片斷。
url

  REST框架包含許多權限類,咱們可使用這些權限類來限制能夠訪問給定視圖的人員。在這種狀況下,咱們正在尋找的是IsAuthenticatedOrReadOnly確保通過身份驗證的請求得到讀寫訪問權限,未經身份驗證的請求得到只讀訪問權限。spa

  首先在視圖模塊中添加如下導入:

from rest_framework import permissions

接着,下面的屬性添加到SnippetListSnippetDetail視圖類。

permission_classes = (permissions.IsAuthenticatedOrReadOnly,)

6、添加登陸API

在適當的urls.py文件中天劍URLconf在添加可瀏覽API的登陸視圖。

from django.conf.urls import include

# 按需添加以下urlconf,r'^api-auth/'模式的部分實際上能夠是您想要使用的任何URL。
urlpatterns += [
    url(r'^api-auth/', include('rest_framework.urls')),
]

7、對象級權限

  咱們但願全部人均可以看到全部代碼片斷,但也要確保只有建立代碼段的用戶才能更新或刪除它。爲此,咱們須要建立一個自定義權限。

在app中建立一個新文件,permissions.py

from rest_framework import permissions


class IsOwnerOrReadOnly(permissions.BasePermission):
    """
    Custom permission to only allow owners of an object to edit it.
    """

    def has_object_permission(self, request, view, obj):
        # Read permissions are allowed to any request,
        # so we'll always allow GET, HEAD or OPTIONS requests.
        # 當用戶請求的爲查詢操做使,對用戶沒有限制
        if request.method in permissions.SAFE_METHODS:
            return True

        # Write permissions are only allowed to the owner of the snippet.
        # 不然判斷用戶是否與操做數據的用戶相同,返回Ture or False
        return obj.owner == request.user    

  添加完以後在SnippetDetail類視圖中添加 permission_classes屬性來將該自定義權限加到代碼中:

  記得導入 IsOwnerOrReadOnly  (from snippets.permissions import IsOwnerOrReadOnly

 

permission_classes = (permissions.IsAuthenticatedOrReadOnly,IsOwnerOrReadOnly,)
相關文章
相關標籤/搜索