[Django-REST-framework教程][04]身份认证与权限

版权声明

本文出自 “ 幻冥极地 ” 博客 ,作者 小貘 采用 署名-非商业性使用-相同方式共享 协议。转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。
https://www.moorehy.com/archives/321

当前我们的 API 对谁可以编辑或删除代码片段(code snippets)没有做任何限制。为了确保以下这些点,我们需要更高级的行为:

  • 代码片段(code snippets)总是与其创建者关联
  • 仅仅被认证的用户可以创建片段(snippets)
  • 只有片段(snippets)的创建者可以更新或删除它
  • 未认证的请求应该仅有只读访问权限。

向我们的模型中添加信息

我们将要对 Snippet 模型类做一些修改。首先,添加一些字段(fields)。其中一个字段将被用来显示创建这个代码片段(code snippet)的用户。其他的字段(field)将被用于存储代码的高亮 HTML 显示。

models.py 文件中添加下面两个字段到 Snippet 模型中。

我们还需要确保,模型保存时会使用 pygments 代码高亮库来填充 highlighted 字段。

我们需要一些额外的导入(imports):

现在我们可以添加一个 .save() 方法到我们的模型类中:

完成上述修改后,我们需要更新下数据表。通常我们会创建一个数据库迁移来完成更新操作,但是为了本教程的目的,这里我们仅仅是删除旧的数据库再重新创建一个。

您可能还想创建一些用来测试 API 的不同的用户。最快的方法就是使用 createsuperuser 命令。

为用户模型添加端点

现在我们得到了一些用来操作的用户,我们最好将这些用户的表现添加到我们的 API 中。很容易的创建一个新的序列化器。在 serializers.py 中添加:

因为在用户模型中 'snippets' 是一个反射关系,当使用 ModelSerializer 类时,它默认不会被包含,所以我们需要为它添加一个明确字段。

我们还要添加一些视图到 views.py 。我们对用户呈现使用只读视图,所以我们将使用基于类的通用视图 ListAPIViewRetrieveAPIView

还要确保导入了 UserSerializer

最后我们需要把这些视图添加到 API ,通过从 URL 配置中引用它们。在 urls.py 中添加下列模式。

将 Users 关系到 Snippets

现在,如果我们创建一个代码片段(code snippet),无法通过 snippet 实例将用户与其创建的 snippet 联系到一起。用户不是作为序列化呈现的一部分被发送的,而是代替传入请求的属性。

我们的处理方式是在我们的 snippet 视图上覆写 .perform_create() 方法,从而允许我们修改实例保存时的处理方式,并处理任何在进入请求或请求 URL 中的隐式信息。

SnippetList 视图类中,添加下列方法:

我们序列化器的 create() 方法现在将被传入一个额外的 owner 字段,连同来自请求中的已验证数据。

更新序列化器

现在 snippets 已经和创建它的用户联系到一起了,让我们更新 SnippetSerializer 使其生效。将下列字段添加到 serializers.py 中的序列化器定义中:

注意:还需要确认添加 'owner', 到内部类 Meta 的字段列表中。

这个字段所做的事非常有趣。 source 参数控制哪个属性被用来填充这个字段,可以指向序列化实例上的任何属性。它还可以使用上面的点标记语法,在这种情况下它将编辑给定属性,和 Django 模板语言中的使用是相似的方式。

我们刚添加的字段是无类型的 ReadOnlyField 类,与其他类型字段(如: CharFieldBooleanField 等)相反,无类型的 ReadOnlyField 总是只读,并且被用于序列化呈现,但在反序列化时不被用于更新模型实例。我们这里还可以使用 CharField(read_only=True)

添加 required 权限到视图

现在代码片段(code snippets)和用户(users)关联到一起了,我们想确保仅有认证的用户可以创建、更新和删除代码片段(code snippets)。

REST 框架包含了一些我们可以用于限制谁可以访问指定视图的权限类。在本案例中,我们需要的是 IsAuthenticatedOrReadOnly ,这将保证被认证的请求获得读写权限,未认证的请求获得只读权限。

首先向视图模块中添加下列导入(import)

然后,为 SnippetListSnippetDetail 视图类添加下列属性。

为可浏览的 API 添加登录

如果您此时打开浏览器并导航到可浏览的 API ,您将发现您不能创建新的代码片段(code snippets)了。为了创建新的 code snippets 我们需要可以作为用户登录。

我们可以使用 browsable API 添加一个登录视图,通过编辑项目级 urls.py 文件中的 URLconf 。

在文件顶部添加下列导入:

然后,在文件底部,增加一个模式来为 browsable API 包含登录登出视图。

模式的 r'^api-auth/' 部分实际上可以设置为任何您想使用的 URL 。唯一的限制是被包含的 url 必须使用 'rest_framework' 的命名空间。在 Django 1.9+ , REST 框架将设置命名空间,所以您可以把它留空。

现在如果再打开浏览器并刷新页面,在页面右上角您将看到一个 ‘Login’ 链接。如果您作为之前已创建的用户登录,您将可以创建 code snippets 。

一旦您已经创建了一些 code snippets ,导航到 ‘/users/’ 端点,就会注意到其中包含了一个 snippets ids 的列表,以及与之关联的每个用户,它们在每个用户的 ‘snippets’ 字段中产生的关联。

对象级权限

我们真的希望所有的 code snippets 可以被任何人看到,但是还需要保证只有创建该 code snippet 的用户可以更新或删除它。

为了做到这点,我们将需要创建一个定制权限。

在 snippets 应用中,创建一个新的文件, permissions.py

现在我们可以添加定制权限到我们的 snippet 实例末端上了,通过编辑 SnippetDetail 视图类中的 permission_classes 属性:

还要确保导入了 IsOwnerOrReadOnly 类。

现在,如果您再次打开浏览器,如果您登录了与创建 code snippet 时相同的用户,您会发现 ‘DELETE’ 和 ‘PUT’ 操作仅出现在 snippet 实例的末端。

通过 API 认证

阴线我们现在有了一组 API 的权限,如果我们想编辑任何 snippets ,我们需要认证我们的请求。我们还没有设置任何 身份认证类 ,所以当前应用了默认配置, SessionAuthenticationBasicAuthentication

当我们通过 Web 浏览器和 API 交互时,我们可以登录,浏览器 session 将提供必要的请求验证。

如果我们以变成方式与 API 交互,我们需要在每个请求中明确提供认证证书。

如果我们尝试在未认证下创建一个 snippet ,我们将得到一个错误:

我们可以通过包含一个我们之前创建的用户的用户名和密码来发出一个成功的请求。

概要

我们现在已经在 Web API 上获得了相当细粒度的权限集,以及系统用户和他们创建的 code snippets 的端点。

教程五 中我们将探讨如何为高亮代码段创建 HTML 端点来讲所有东西组合在一起,并通过系统内关联的超链接来提高我们 API 的衔接。

One thought on “[Django-REST-framework教程][04]身份认证与权限

发表评论

电子邮件地址不会被公开。 必填项已用*标注