当前我们的API在编辑或者删除的时候没有任何限制,我们不希望有些人有高级的行为,确保:

  • 代码段始终与创建者相关联
  • 只允许授权的用户可以创建代码段
  • 只允许代码段创建者可以更新和删除
  • 没有认证的请求应该有一个完整的只读权限列表

添加用户信息在我们的models中

我们将对snippet models 进行一些更改,首先,让我们添加一对fields,其中一个跟我们的用户表关联,剩下一个字段用作存储高亮的html,还需要导入pygments库来高亮code,最后需要重新定义save方法,添加一些我们自定义配置

修改后的models如下

from django.db import modelsfrom pygments.lexers import get_all_lexers
from pygments.styles import get_all_styles
from pygments.lexers import get_lexer_by_name
from pygments.formatters.html import HtmlFormatter
from pygments import highlightLEXERS = [item for item in get_all_lexers() if item[1]]
LANGUAGE_CHOICES = sorted([(item[1][0], item[0]) for item in LEXERS])
STYLE_CHOICES = sorted((item, item) for item in get_all_styles())class Snippet(models.Model):created = models.DateTimeField(auto_now_add=True)title = models.CharField(max_length=100, blank=True, default='')code = models.TextField()linenos = models.BooleanField(default=False)language = models.CharField(choices=LANGUAGE_CHOICES, default='python', max_length=100)style = models.CharField(choices=STYLE_CHOICES, default='friendly', max_length=100)owner = models.ForeignKey('auth.User', related_name='snippets', on_delete=models.CASCADE)highlighted = models.TextField()def save(self, *args, **kwargs):"""Use the `pygments` library to create a highlighted HTMLrepresentation of the code snippet."""lexer = get_lexer_by_name(self.language)linenos = self.linenos and 'table' or Falseoptions = 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)class Meta:ordering = ('created',)

接下来我们需要将新字段在数据库中添加,为了中间不必要的麻烦,现在我们直接删除原来的库和migration目录,重新生成

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

最后我们需要创建一个超级用户来测试API,使用createsuperuser来快速创建

python manage.py createsuperuser

为我们user models添加serializers

我们需要在serializers.py中添加

from django.contrib.auth.models import Userclass UserSerializer(serializers.ModelSerializer):snippets = serializers.PrimaryKeyRelatedField(many=True, queryset=Snippet.objects.all())class Meta:model = Userfields = ('id', 'username', 'snippets')

因为'snippets'是User模型上的反向关系,所以在使用ModelSerializer类时,它不会被默认包含,因此我们需要为它添加一个显式字段。

我们还会向views.py添加几个视图。我们只想对用户表示使用只读视图,因此我们将使用ListAPIView和RetrieveAPIView通用类的视图。

from django.contrib.auth.models import User
from snippets.serializers import UserSerializerclass UserList(generics.ListAPIView):queryset = User.objects.all()serializer_class = UserSerializerclass UserDetail(generics.RetrieveAPIView):queryset = User.objects.all()serializer_class = UserSerializer

最后我们需要为刚才的user 视图添加url配置,修改urls.py

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

将代码段与用户关联

现在,如果我们创建了代码段,就无法将创建代码段的用户与代码段实例相关联。用户不作为序列化表示的一部分发送,而是传入请求的属性。
我们处理它的方式是通过在我们的代码片段视图上覆盖一个.perform_create()方法,允许我们修改实例保存的方式,并处理在传入请求或请求的URL中隐含的任何信息。
在我们SnippetList 视图类中,添加下面的方法

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

当我们的serializer里create()方法被调用时,将自动添加owner字段和验证合法的请求数据

更新我们的seralizer

现在sippets创建的时候已经和我们的用户关联起来,让我们更新我们的SnippetSerializer,添加以下定义的字段:

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

source参数用于控制那个属性被用来填充字段,并且可以指向序列化实例上的任何属性。 它也可以采用上面所示的虚线符号,在这种情况下,它将遍历给定的属性,与使用Django的模板语言类似的方式。
我们添加的字段是无类型的ReadOnlyField类,与其他类型的字段,例如CharField,BooleanField等相反。无类型的ReadOnlyField总是只读的,并且将用于序列化表示,但不会 用于在反序列化时更新模型实例。 我们也可以在这里使用CharField(read_only = True)。
同时需要在meta class中添加owner字段

class Meta:model = Snippetfields = ('id', 'title', 'code', 'linenos', 'language', 'style','owner')

在views中添加请求权限

现在snippets 已经和我们的用户关联上了,我们需要确保仅仅通过验证的用户能够增删改

REST framework 包含有一些权限类,我们可以用来限制谁可以访问给定的视图,在这种情况下,首先我们查找IsAuthenticatedOrReadOnl,这将确保已验证的请求获得读写访问权限,并且未验证的请求获得只读访问权限。

首先在module中导入permissions,

from rest_framework import permissions

然后在SnippetListSnippetDetail view中添加下面这个属性

permission_classes = (permissions.IsAuthenticatedOrReadOnly,)

添加登陆WEB API

如果您打开浏览器并转到可浏览的API,您会发现您无法再创建新的代码段。为此,我们需要能够以用户身份登录。

我们可以通过编辑项目级urls.py文件中的URLconf来添加一个登录视图,以便与可浏览的API一起使用
编辑urls.py,添加如下内容

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

r'^api-auth/' 这个可以自定义,但是后面的namespace必须使用rest_framework作命名空间,但是在django1.9+版本,自动设置,不需要添加
现在,如果您再次打开浏览器并刷新页面,您将在页面右上角看到一个“登录”链接。如果您以之前创建的用户之一登录,则可以再次创建代码段
创建几个代码段后,转到“/ users /”端点,并注意该表示中包含每个用户的“代码段”字段中与每个用户相关联的代码段ID列表。

对象级别的权限

我们希望所有的代码片段对任何人都可见,但也确保只有创建代码片段的用户能够更新或删除它。为了实现这个,我们需要创建一个自定义权限
在snippets.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

现在我们在SnippetDetail view中通过编辑permission_classes属性为snippet实例中添加自定义的权限

permission_classes = (permissions.IsAuthenticatedOrReadOnly,IsOwnerOrReadOnly,)

同时确保导入了自定的权限类

from snippets.permissions import IsOwnerOrReadOnly

现在,如果您再次打开浏览器,则会发现如果您以创建代码段的同一用户身份登录,则“DELETE”和“PUT”操作只会显示在代码段实例端点上。

使用api进行身份验证

因为我们现在有一组API的权限,如果我们想要编辑任何snippet,我们需要使用SessionAuthenticationBasicAuthentication验证我们的请求
当我们通过Web浏览器与API交互时,我们可以登录,然后浏览器会话将为请求提供所需的身份验证。
如果我们以编程方式与API交互,我们需要在每个请求中显式提供身份验证凭据。
如果我们尝试创建一个未验证的代码段,我们会收到一条错误:

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

我们在请求的时候加入验证,我们将可以创建:

curl  -X POST  -s -u test:1234.com -H "Content-Type:application/json"  -d  '{"title": "sec test","code": "python asdasdas manasdnasd", "linenos": false,"language": "python","style": "vim","owner": "fuzengjie"}' http://127.0.0.1:8000/snippets/ | jq .
{"id": 2,"title": "sec test","code": "python asdasdas manasdnasd","linenos": false,"language": "python","style": "vim","owner": "test"
}

转载于:https://www.cnblogs.com/pycode/p/6525456.html

django restframwork 教程之authentication权限相关推荐

  1. linux运维管理系统培训,Linux运维教程之Linux系统用户与组管理

    今天小编要跟大家分享的文章是关于Linux运维教程之Linux系统用户与组管理.正在从事Linux运维工作和学习的小伙伴们来和小编一起看一看吧,希望本篇文章能够对大家有所帮助. 一.Linux系统用户 ...

  2. anaconda的python使用教程-Python安装教程之Anaconda入门使用总结

    原标题:Python安装教程之Anaconda入门使用总结 如今参加Python培训学习Python开发的小伙伴对Python安装教程比较感兴趣,本篇文章小编就和读者们分享一下Python安装教程之A ...

  3. 乐鑫代理-启明云端分享ESP32系列教程之二:Linux搭建esp-idf环境

    提示:此教程依据乐鑫官方的ESP32入门教程总结而来,仅供个人参考学学习,如有错误,欢迎批评指正.乐鑫官方参考: 乐鑫官方文档地址 1.搭建esp-idf环境 1.1安装虚拟机与Ubuntu 未安装请 ...

  4. java+mysql性能优化_Java培训实战教程之mysql优化

    Java培训实战教程之mysql优化 更新时间:2015年12月29日13时30分 来源:传智播客Java培训学院 浏览次数: 1.   mysql引擎 1.1.  引擎类型 MySQL常用的存储引擎 ...

  5. 【SAP PO】SAP PO 接口配置完整教程之二REST服务对接

    SAP PO 接口配置完整教程之二REST服务对接 1.了解服务协议 1.1.服务通讯协议 1.2.具体接口协议 1.3.接口服务测试 2.PO端接口配置 2.1.PO端ESR配置 2.2.PO端IB ...

  6. DNS域欺骗攻击详细教程之Windows篇

    一.DNS域欺骗攻击原理 DNS欺骗即域名信息欺骗是最常见的DNS安全问题.当一个DNS服务器掉入陷阱,使用了来自一个恶意DNS服务器的错误信息,那么该DNS服务器就被欺骗了.DNS欺骗会使那些易受攻 ...

  7. SwiftUI 语音合成与语言识别教程之 03 实现录音文件转文字(含完整项目源码)SFSpeechURLRecognitionRequest

    前期知识回顾 <SwiftUI 语音合成与语言识别教程之 01 Speech框架简介>我们介绍了Speech框架是什么,知道了可以使用Speech进行多语言识别. <SwiftUI ...

  8. Kail Linux渗透测试教程之在Metasploit中扫描

    Kail Linux渗透测试教程之在Metasploit中扫描 在Metasploit中扫描 在Metasploit中,附带了大量的内置扫描器.使用这些扫描器可以搜索并获得来自一台计算机或一个完整网络 ...

  9. Wear OS手表应用开发教程之-Activity使用微光模式-AmbientModeSupport

    本文目录 点击直达 Wear OS手表应用开发系列教程 点击直达 本文标签 `路过的年轻人啊,你是要用左手点个赞呢,还是要右手点个关注呢` 前言: 使用方法: 结语: 最后我还有一句话要说: 人生下来 ...

最新文章

  1. DispatcherServlet的启动和初始化
  2. 一句话说汽车(超搞笑)
  3. 根据屏幕分辨率获取css,根据判断浏览器类型屏幕分辨率自动调用不同CSS的代码...
  4. boost::math模块计算贝塞尔函数的零点的测试程序
  5. eclipse入门指南
  6. nginx的日志配置
  7. 分计算iv值_快捷、经济、实用的光伏及IV曲线测试仪PVPM 1500X
  8. Register DLL and OCX
  9. DIV+CSS:页脚永远保持在页面底部
  10. 聊天室自动滚动效果实现
  11. Redis 命令 - 在线参考
  12. PPT怎么设置html颜色代码,PPT怎么设置表格边框颜色 PPT设置表格边框颜色教程
  13. Windows安全加固系列---日志配置操作
  14. ONF定义的SDN架构
  15. uniapp插件市场-涂图视频编辑-美妆-剪辑-微整形原生sdk插件发布-优雅草科技
  16. Can#39;t locate Tk.pm
  17. 计步器算法简述和模块使用
  18. 2020CCPC绵阳K.Knowledge is Power(互质数分解)+两数互质规律总结
  19. java 下载junit的jar包_junit4下载-Junit4.11完整包【附使用方法】-东坡下载
  20. 获取三个数的中间值 宏

热门文章

  1. 计算机视觉识别简史:从 AlexNet、ResNet 到 Mask RCNN
  2. 大数据应用项目创新大赛_第二届海南大数据创新应用大赛收官
  3. python爬虫学习:电商数据分析
  4. rxjs为什么用的人少_工伤为什么公司不怕打官司
  5. JDK 5、6、7、8、9、10、11、12、13、14 新特性汇总
  6. Chrome 错误代码:ERR_UNSAFE_PORT
  7. rust睡觉按键没反应_腐蚀Rust有哪些实用操作 腐蚀Rust实用操作汇总-游侠网
  8. java hashcode 例子_Java UUID hashCode()用法及代码示例
  9. c++高斯投影正反算_为何买手机要选Type-C接口的?除充电快以外,还隐藏这4个妙用...
  10. python判断奇数_python 中x%2 x1 判断偶数奇数 性能对比