Django REST framework 第四章 Authentication

到目前为止,撰写的API没有任何限制关于谁能更新、删除snippet. 我们更想要一些高级行为来确保:

1、代码段总是跟创建者有关联

2、只要认证通过的用户才能创建

3、只有创建者有权限更新或者删除

4、没有认证的请求应该有且只有完全的只读权限

Adding information to our model

我们打算在Snippet模型类上做一些改变。首先,添加一些字段,其中之一用来代表创建这个code的用户。其他的字段将用于存储代码中突出显示的HTML表示形式。

添加下面两个字段到Snippet类在models.py.

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

现在需要往model类里面添加一个save方法:

def save(self, *args, **kwargs):
    """
    Use the `pygments` library to create a highlighted HTML
    representation of the code snippet.
    """
    lexer = get_lexer_by_name(self.language)
    linenos = ‘table‘ if self.linenos else False
    options = {‘title‘: self.title} if self.title else {}
    formatter = HtmlFormatter(style=self.style, linenos=linenos,
                              full=True, **options)
    self.highlighted = highlight(self.code, lexer, formatter)
    super(Snippet, self).save(*args, **kwargs)

做好上面的操作后,需要同步数据库

shuais-MacBook-Pro:TestApp dandyzhang$ rm -f db.sqlite3
shuais-MacBook-Pro:TestApp dandyzhang$ rm -r app01/migrations
shuais-MacBook-Pro:TestApp dandyzhang$ python3 manage.py makemigrations
shuais-MacBook-Pro:TestApp dandyzhang$ python3 manage.py migrate

为了测试API,还需要创建一下超级用户:

shuais-MacBook-Pro:TestApp dandyzhang$ python3 manage.py createsuperuser

Adding endpoints for our User models

现在我们已经有一些工作的用户了,还需要添加这些用户的表示到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‘)

snippets在 User model上是一种反转关系,在继承ModelSerializer类不能使用默认值。所以需要为它添加一个明确的字段

同样,也需要在views.py文件内添加一些东西。我们更倾向于为用户表示使用只读权限,所以我们将使用ListAPIView和RetrieveAPIView generic CBV.

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 app01.serializers import UserSerializer

最后,我们需要把这些视图添加进API,通过url设置,在urls.py文件中

    path(‘users/‘, views.UserList.as_view()),
    path(‘users/<int:pk>/‘, views.UserDetail.as_view()),

Associating Snippets with Users

现在,如果我们创建snippet,会发现没有办法通过snippet实例关联到创建的用户。用户不是作为序列化表示的一部分发送的,而是即将到来的请求的属性。

解决这个问题的方式是重写一个.perform_create()方法在views里面,它允许我们修改管理实例如何保存,处理传入请求或者被请求URL的任何信息

在SnippetList视图类添加如下的方法:

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

一个额外添加的owner字段现在将会被serializer里面的create方法通过,跟请求里面的验证数据一起。

Updating our serializer

现在snippets和用户的关联建好了,更新一下SnippetSerializer来反应它。在serializers.py文件添加:

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

注意将它添加在Meta类的内部.

这个字段做了些很有趣的事情。source参数控制一种属性用来跟某个字段关联对应,可以指向序列化实例的任何属性。它也可以采用上面所显示的实例的表示法,将会遍历给定的属性,跟Django的模版语言很类似。

我们刚刚添加的这个字段是一个非类型化的ReadOnlyField类,与其他类型字段相反,比如CharField、BooleanField等...非类型话的ReadOnlyField总是只读的,并将用于序列化表示,但是在反序列化的时候不能被用来更新模型实例,也可以用CharField(read_only=True)

Adding required permissions to views

现在snippet已经跟用户有联系了,我们想确定只有通过验证的用户可以创建,更新,删除snippet。

REST framework包含了一串权限类供用来限制谁能访问一个给定的视图。在这里,我们想要寻找的是IsAuthenticatedOrReadOnly这个类用来确保通过验证的请求获取到读写权限,没有通过验证的请求获得只读权限。

首先在views里面导入模块

from rest_framework import permissions

然后添加下面的属性到SnippetList和SnippetDetail两个视图类中。

permission_classes = (permissions.IsAuthenticatedOrReadOnly,)

Adding login to Browable API

如果你打开浏览器,导航到了可浏览的API,你会发现你不能再创建新的spnippet了。为了能这样做,需要先登陆。

我们可以再根目录的urls文件内加入下面的路由,它包含可浏览的API的登陆和登出。

    path(‘api/‘, include(‘rest_framework.urls‘, namespace=‘rest_framework‘)),

路由的名称可以自定义。

现在打开浏览器,你会在网页的右上角看到login的图标。如果你用之前创建的用户登陆了,你就可以再一次创建snippet了。

创建好一些snippet后,你就可以在子路由users下面查看到

Object level permissions

我们想让所有的snippet被任何人看到,但必须保证只有创建的人才可以增删改。

想要这么做,需要创建一个定制化的权限。创建一个新的文件在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.
        return obj.owner == request.user

现在可以添加自定义的权限到snippet实例终端,通过编辑在SnippetDetail视图类里面的permission_classes属性

from app01.permissions import IsOwnerOrReadOnly  # 先导入

permission_classes = (permissions.IsAuthenticatedOrReadOnly,
                      IsOwnerOrReadOnly,)

现在重新运行一下此项目,你会发现delete和put按钮出现在你创建的一个snippet实例的终端。

Authenticating with the API

因为现在已经有一批权限在API上,如果需要编辑任何的snippet需要认证请求。但是我们还没有设置任何的认证类,所以此时是使用的默认的类SessionAuthentication和BasicAuthentication

当我们通过浏览器跟API进行交互,我们可以登陆,然后浏览器的session会提供必要的认证给请求。如果我们以变成的方式跟API交互,就需要提供明确的认证凭据在每一次请求上。如果尝试创建一个新的snippet不带验证,将会得到报错:

带上认证凭据:

原文地址:https://www.cnblogs.com/wuzdandz/p/9460508.html

时间: 2024-08-01 12:11:27

Django REST framework 第四章 Authentication的相关文章

Django REST framework 第五章 Relationships &amp; Hyperlinked APIs

到目前为止,API内部的关系是使用主键来代表的.在这篇教程中,我们将提高API的凝聚力和可发现性,通过在相互关系上使用超链接. Creating an endpoint for the root of our API 现在,我们已经有了snippets和users的终端,但是没有一个单独的终端指向我们的API.使用之前常规的FBV方式和@api_view装饰器创建一个.在你的app的views文件内 from rest_framework.decorators import api_view f

《Entity Framework 6 Recipes》中文翻译系列 (20) -----第四章 ASP.NET MVC中使用实体框架之在MVC中构建一个CRUD示例

翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 第四章  ASP.NET MVC中使用实体框架 ASP.NET是一个免费的Web框架,它支持3种不同的技术来创建websites(网站)和Web应用:他们分别是,Web Pages,Web Forms,和MVC.虽然MVC是一种非常流行的,有完整的用于软件开发模式理论的技术,但它在ASP.NET中却是一种新的技术. 目前最新的版本是2012年发布的ASP.NET MVC4.自从2008年发布

Python【第二十四课】Django rest framework

本节内容 Django rest framework 安装 Django rest framwwork 环境配置 简单举例说明 Django中使用 rest framework 1.1 安装 Django rest framework 建立新的环境 virtualenv env source env/bin/activate 安装 djangorestframework 模块 pip install django pip install djangorestframework pip insta

Django REST framework 的TokenAuth认证及外键Serializer基本实现

一,Models.py中,ForeignKey记得要有related_name属性,已实现关联对象反向引用. app_name = models.ForeignKey("cmdb.App",related_name='deploy_app', verbose_name="App") 二,Settings.py文件中,加入对Django REST framework的基本设置. REST_FRAMEWORK = { 'DEFAULT_PERMISSION_CLASSE

Django Rest Framework(2)

一.认证(补充的一个点) 认证请求头 1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 from rest_framework.views import APIView 4 from rest_framework.response import Response 5 from rest_framework.authentication import BaseAuthentication 6 from rest_framework.permiss

Django Restful Framework【第三篇】认证、权限、限制访问频率

一.认证 认证请求头 views.py #!/usr/bin/env python # -*- coding:utf-8 -*- from rest_framework.views import APIView from rest_framework.response import Response from rest_framework.authentication import BaseAuthentication from rest_framework.permissions import

Django Rest Framework源码剖析(二)-----权限

一.简介 在上一篇博客中已经介绍了django rest framework 对于认证的源码流程,以及实现过程,当用户经过认证之后下一步就是涉及到权限的问题.比如订单的业务只能VIP才能查看,所以这时候需要对权限进行控制.下面将介绍DRF的权限控制源码剖析. 二.基本使用 这里继续使用之前的示例,加入相应的权限,这里先介绍使用示例,然后在分析权限源码 1.在django 项目下新建立目录utils,并建立permissions.py,添加权限控制: class MyPremission(obje

Django Rest Framework源码剖析(三)-----频率控制

一.简介 承接上篇文章Django Rest Framework源码剖析(二)-----权限,当服务的接口被频繁调用,导致资源紧张怎么办呢?当然或许有很多解决办法,比如:负载均衡.提高服务器配置.通过代理限制访问频率等,但是django rest framework自身就提供了访问频率的控制,可以从代码本身做控制. 二.频率控制内部原理概述 django rest framework 中频率控制基本原理基于访问次数和时间,通过计算实现,当然我们也可以自己定义频率控制方法.基本原理如下: 启用频率

Django Rest Framework源码剖析(八)-----视图与路由

一.简介 django rest framework 给我们带来了很多组件,除了认证.权限.序列化...其中一个重要组件就是视图,一般视图是和路由配合使用,这种方式给我们提供了更灵活的使用方法,对于使用者而言不同的视图具有不同的功能,这样我们可以根据需求定制自己视图.以下是官网传送门:http://www.django-rest-framework.org/api-guide/views/ 在之前的文章中,由于参杂了权限.认证等(如果不了解请看博客的以前的文章),但在本章中基本可以不使用,所进使