99re热这里只有精品视频,7777色鬼xxxx欧美色妇,国产成人精品一区二三区在线观看,内射爽无广熟女亚洲,精品人妻av一区二区三区

Django drf 認證和權限

2020-01-22 11:22 更新

目前,我們的API對誰可以編輯或刪除代碼段沒有任何限制。我們希望有更高級的行為,以確保:

  • 代碼片段始終與創(chuàng)建者相關聯。
  • 只有通過身份驗證的用戶可以創(chuàng)建片段。
  • 只有代碼片段的創(chuàng)建者可以更新或刪除它。
  • 未經身份驗證的請求應具有完全只讀訪問權限。

在我們的模型(model)中添加信息

我們將對我們的Snippet模型類進行幾次更改。首先,我們添加幾個字段。其中一個字段將用于表示創(chuàng)建代碼段的用戶,另一個字段將用于存儲代碼的高亮顯示的HTML內容。

將以下兩個字段添加到models.py文件中的Snippet模型中。

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

我們還需要確保在保存模型時,使用pygments代碼高亮顯示庫填充要高亮顯示的字段。

我們需要導入額外的模塊:

from pygments.lexers import get_lexer_by_name
from pygments.formatters.html import HtmlFormatter
from pygments import highlight

現在我們可以在我們的模型類中添加一個.save()方法:

def save(self, *args, **kwargs):
    """
    使用`pygments`庫創(chuàng)建一個高亮顯示的HTML表示代碼段。
    """
    lexer = get_lexer_by_name(self.language)
    linenos = self.linenos and 'table' or False
    options = self.title and {'title': self.title} or {}
    formatter = HtmlFormatter(style=self.style, linenos=linenos,
                              full=True, **options)
    self.highlighted = highlight(self.code, lexer, formatter)
    super(Snippet, self).save(*args, **kwargs)

完成這些工作后,我們需要更新我們的數據庫表。 通常這種情況我們會創(chuàng)建一個數據庫遷移(migration)來實現這一點,但現在我們只是個教程示例,所以我們選擇直接刪除數據庫并重新開始。

rm -f tmp.db db.sqlite3
rm -r snippets/migrations
python manage.py makemigrations snippets
python manage.py migrate

你可能還需要創(chuàng)建幾個不同的用戶,以用于測試API。最快的方法是使用createsuperuser命令。

python manage.py createsuperuser

為我們的用戶模型添加路徑

現在我們已經創(chuàng)建了一些用戶,我們最好在API中添加這些用戶的表示。創(chuàng)建一個新的序列化器非常簡單,在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')

因為'snippets' 在用戶模型中是一個反向關聯關系。在使用 ModelSerializer 類時它默認不會被包含,所以我們需要為它添加一個顯式字段。

我們還會在views.py中添加幾個視圖。我們只想將用戶展示為只讀視圖,因此我們將使用ListAPIView和RetrieveAPIView通用的基于類的視圖。

from django.contrib.auth.models import User


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


class UserDetail(generics.RetrieveAPIView):
    queryset = User.objects.all()
    serializer_class = UserSerializer

確保導入了UserSerializer類

from snippets.serializers import UserSerializer

最后,我們需要通過在URL conf中引用它們來將這些視圖添加到API中。將以下內容添加到urls.py文件的patterns中。

url(r'^users/$', views.UserList.as_view()),
url(r'^users/(?P<pk>[0-9]+)/$', views.UserDetail.as_view()),

將Snippet和用戶關聯

現在,如果我們創(chuàng)建了一個代碼片段,并不能將創(chuàng)建該代碼片段的用戶與代碼段實例相關聯。用戶不是作為序列化表示的一部分發(fā)送的,而是作為傳入請求的屬性。(譯者注:user不在傳過來的數據中,而是通過request.user獲得)

我們處理的方式是在我們的代碼片段視圖中重寫一個.perform_create()方法,這樣我們可以修改實例保存的方法,并處理傳入請求或請求URL中隱含的任何信息。

在SnippetList視圖類中,添加以下方法:

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

我們的序列化器的create()方法現在將被傳遞一個附加的'owner'字段以及來自請求的驗證數據。

更新我們的序列化器

現在,這些代碼片段和創(chuàng)建它們的用戶相關聯,讓我們更新我們的SnippetSerializer來體現這個關聯關系。將以下字段添加到serializers.py中的序列化器定義: Add the following field to the serializer definition in serializers.py:

owner = serializers.ReadOnlyField(source='owner.username')

注意:確保你還將'owner',添加到內部Meta類的字段列表中。

這個字段非常有趣。source參數控制哪個屬性用于填充字段,并且可以指向序列化實例上的任何屬性。它也可以采用如上所示點加下劃線的方式,在這種情況下,它將以與Django模板語言一起使用的相似方式遍歷給定的屬性。

我們添加的字段是無類型的ReadOnlyField類,區(qū)別于其他類型的字段(如CharField,BooleanField等)。無類型的ReadOnlyField始終是只讀的,只能用于序列化表示,不能用于在反序列化時更新模型實例。我們也可以在這里使用CharField(read_only=True)。

添加視圖所需的權限

現在,代碼片段與用戶是相關聯的,我們希望確保只有經過身份驗證的用戶才能創(chuàng)建,更新和刪除代碼片段。

REST框架包括許多權限類,我們可以使用這些權限類來限制誰可以訪問給定的視圖。 在這種情況下,我們需要的是IsAuthenticatedOrReadOnly類,這將確保經過身份驗證的請求獲得讀寫訪問權限,未經身份驗證的請求將獲得只讀訪問權限。

首先要在視圖模塊中導入以下內容

from rest_framework import permissions

然后,將以下屬性添加到SnippetList和SnippetDetail視圖類中。

permission_classes = (permissions.IsAuthenticatedOrReadOnly,)

給Browsable API添加登陸

如果你打開瀏覽器并瀏覽我們的API,那么你會發(fā)現不能創(chuàng)建新的代碼片段。只有登陸用戶才能創(chuàng)建新的代碼片段。

我們可以通過編輯項目級別的urls.py文件中的URLconf來添加可瀏覽的API使用的登錄視圖。

在文件頂部添加以下導入:

from django.conf.urls import include

而且,在文件末尾添加一個模式(pattern)以包括可瀏覽的API的登錄和注銷視圖。

urlpatterns += [
    url(r'^api-auth/', include('rest_framework.urls',
                               namespace='rest_framework')),
]

模式的r'^api-auth/'部分實際上可以是你要使用的任何URL。唯一的限制是包含的URL必須使用'rest_framework'命名空間。在Django 1.9以上的版本中,REST框架將設置命名空間,因此你可以將其刪除。

現在,如果你再次打開瀏覽器并刷新頁面,你將在頁面右上角看到一個“登錄”鏈接。如果你用早期創(chuàng)建的用戶登錄,就可以再次創(chuàng)建代碼片段。

一旦你創(chuàng)建了一些代碼片段后,在'/users/'路徑下你會注意到每個用戶的'snippets'字段都包含與每個用戶相關聯的代碼片段的列表。

對象級別的權限

我們希望所有的代碼片段都可以被任何人看到,但也要確保只有創(chuàng)建代碼片段的用戶才能更新或刪除它。

為此,我們將需要創(chuàng)建一個自定義權限。

在snippets app中,創(chuàng)建一個新文件permissions.py。

from rest_framework import permissions


class IsOwnerOrReadOnly(permissions.BasePermission):
    """
    自定義權限只允許對象的所有者編輯它。
    """

    def has_object_permission(self, request, view, obj):
        # 讀取權限允許任何請求,
        # 所以我們總是允許GET,HEAD或OPTIONS請求。
        if request.method in permissions.SAFE_METHODS:
            return True

        # 只有該snippet的所有者才允許寫權限。
        return obj.owner == request.user

現在,我們可以通過在SnippetDetail視圖類中編輯permission_classes屬性將該自定義權限添加到我們的代碼片段實例路徑:

permission_classes = (permissions.IsAuthenticatedOrReadOnly,
                      IsOwnerOrReadOnly,)

確保要先導入IsOwnerOrReadOnly類。

from snippets.permissions import IsOwnerOrReadOnly

現在,如果再次打開瀏覽器,你會發(fā)現如果你以代碼片段創(chuàng)建者的身份登錄的話,“DELETE”和“PUT”操作才會顯示在代碼片段實例路徑上。

使用API??進行身份驗證

現在因為我們在API上有一組權限,如果我們要編輯任何代碼片段,我們都需要驗證我們的請求。我們還沒有設置任何身份驗證類,所以應用的是默認的SessionAuthentication和BasicAuthentication。

當我們通過Web瀏覽器與API進行交互時,我們可以登錄,然后瀏覽器會話將為請求提供所需的身份驗證。

如果我們在代碼中與API交互,我們需要在每次請求上顯式提供身份驗證憑據。

如果我們通過沒有驗證就嘗試創(chuàng)建一個代碼片段,我們會像下面展示的那樣收到報錯:

http POST http://127.0.0.1:8000/snippets/ code="print 123"

{
    "detail": "Authentication credentials were not provided."
}

我們可以通過加上我們之前創(chuàng)建的一個用戶的用戶名和密碼來成功創(chuàng)建:

http -a tom:password123 POST http://127.0.0.1:8000/snippets/ code="print 789"

{
    "id": 5,
    "owner": "tom",
    "title": "foo",
    "code": "print 789",
    "linenos": false,
    "language": "python",
    "style": "friendly"
}

總結

我們現在已經在我們的Web API上獲得了相當精細的一組權限控制,并為系統(tǒng)的用戶和他們創(chuàng)建的代碼片段提供了API路徑。


以上內容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號