django restframwork 教程之authentication权限
当前我们的API在编辑或者删除的时候没有任何限制,我们不希望有些人有高级的行为,确保:
- 代码段始终与创建者相关联
- 只允许授权的用户可以创建代码段
- 只允许代码段创建者可以更新和删除
- 没有认证的请求应该有一个完整的只读权限列表
添加用户信息在我们的models中
我们将对snippet models 进行一些更改,首先,让我们添加一对fields,其中一个跟我们的用户表关联,剩下一个字段用作存储高亮的html,还需要导入pygments库来高亮code,最后需要重新定义save方法,添加一些我们自定义配置
修改后的models如下
from django.db import models
from 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 highlight
LEXERS = [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 HTML
representation of the code snippet.
"""
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)
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 User
class UserSerializer(serializers.ModelSerializer):
snippets = serializers.PrimaryKeyRelatedField(many=True, queryset=Snippet.objects.all())
class Meta:
model = User
fields = ('id', 'username', 'snippets')
因为'snippets'是User模型上的反向关系,所以在使用ModelSerializer类时,它不会被默认包含,因此我们需要为它添加一个显式字段。
我们还会向views.py添加几个视图。我们只想对用户表示使用只读视图,因此我们将使用ListAPIView和RetrieveAPIView通用类的视图。
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
最后我们需要为刚才的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 = Snippet
fields = ('id', 'title', 'code', 'linenos', 'language', 'style','owner')
在views中添加请求权限
现在snippets 已经和我们的用户关联上了,我们需要确保仅仅通过验证的用户能够增删改
REST framework 包含有一些权限类,我们可以用来限制谁可以访问给定的视图,在这种情况下,首先我们查找IsAuthenticatedOrReadOnl
,这将确保已验证的请求获得读写访问权限,并且未验证的请求获得只读访问权限。
首先在module中导入permissions,
from rest_framework import permissions
然后在SnippetList
和 SnippetDetail
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,我们需要使用SessionAuthentication
和BasicAuthentication
验证我们的请求
当我们通过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"
}
django restframwork 教程之authentication权限的更多相关文章
- django restframwork教程之Request和Response
从这一篇文章开始,我们会覆盖整个REST framwork框架的核心,接下来让我们介绍一些基础的构建块 Request 对象 REST framework 引入了一个扩展HttpRequest的请求对 ...
- django restframework 教程之Serialization(序列化)
介绍 本教程将会通过创建一个简单的粘贴代码项目,突出显示WebAPI,过程中,会介绍组成REST框架的各种组件,让你全面了解如何配合使用. 环境设置 建议使用virtualenv建立新的虚拟环境,确保 ...
- kali linux 系列教程之metasploit 连接postgresql可能遇见的问题
kali linux 系列教程之metasploit 连接postgresql可能遇见的问题 文/玄魂 目录 kali linux 下metasploit 连接postgresql可能遇见的问题. ...
- kali Linux系列教程之BeFF安装与集成Metasploit
kali Linux系列教程之BeFF安装与集成Metasploit 文/玄魂 kali Linux系列教程之BeFF安装与集成Metasploit 1.1 apt-get安装方式 1.2 启动 1. ...
- DNS域欺骗攻击详细教程之Linux篇
.DNS域欺骗攻击原理 DNS欺骗即域名信息欺骗是最常见的DNS安全问题.当一 个DNS服务器掉入陷阱,使用了来自一个恶意DNS服务器的错误信息,那么该DNS服务器就被欺骗了.DNS欺骗会使那些易受攻 ...
- Spring 系列教程之 bean 的加载
Spring 系列教程之 bean 的加载 经过前面的分析,我们终于结束了对 XML 配置文件的解析,接下来将会面临更大的挑战,就是对 bean 加载的探索.bean 加载的功能实现远比 bean 的 ...
- BeagleBone Black教程之BeagleBone Black使用到的Linux基础
BeagleBone Black教程之BeagleBone Black使用到的Linux基础 BeagleBone Black涉及到的Linux基础 在许多没有Linux相关经验的人看来,Linux看 ...
- ArduinoYun教程之Arduino编程环境搭建
ArduinoYun教程之Arduino编程环境搭建 Arduino编程环境搭建 通常,我们所说的Arduino一般是指我们可以实实在在看到的一块开发板,他可以是Arduino UNO.Arduino ...
- Kail Linux渗透测试教程之在Metasploit中扫描
Kail Linux渗透测试教程之在Metasploit中扫描 在Metasploit中扫描 在Metasploit中,附带了大量的内置扫描器.使用这些扫描器可以搜索并获得来自一台计算机或一个完整网络 ...
随机推荐
- 【吉比特】G-bits2018校园春季招聘技术类岗位笔试经验
笔试公司:厦门吉比特网络技术股份有限公司 笔试岗位:游戏研发工程师 笔试时间:2018年3月30日19:00-20:30 笔试形式:牛客网在线做题 笔试回忆: 笔试总共时长1小时半,共52道题.其中选 ...
- php 文件上传类,功能相当齐全,留作开发中备用吧。
收藏一个经典好用的php 文件上传类,功能相当齐全,留作开发中备用吧. 好东西,大家都喜欢,才是真的好,哈哈!!! <?php /** * 文件上传类 */ class upload ...
- ckeditor4.2.1常用配置
常用的配置信息都放在根目录的config.js文件中,一些常用的配置项如下: 1.界面语言 //语言 config.language = 'zh-cn'; 2.字体添加中文 //字体 config.f ...
- 6.查找单链表中的倒数第k个结点
普通思路:先将整个链表从头到尾遍历一次,计算出链表的长度size,得到链表的长度之后,就好办了,直接输出第(size-k)个节点就可以了(注意链表为空,k 为0,k为1,k大于链表中节点个数时的情况) ...
- MyEclipse如何恢复删掉的文件
今天一不小心删了项目里的两个包,心里那个痛啊,一想MyEclipse这么强大,应该会有恢复文件的功能吧,要不就太坑了啊. 果不其然让我找到了方法: 如图:右击项目选择 然后在弹出的页面勾选需要恢复的文 ...
- VCL 中的 Windows API 函数(5): AlphaBlend
AlphaBlend 是指定图像混合透明的函数, 在 Graphics.GraphUtil.RibbonStyleActnCtrls 单元用到. 下面的测试是把一张图片显示在窗体, 并可以调整透明度. ...
- 在ListView中使用GridView, Style这样写:
参考:http://msdn.microsoft.com/zh-cn/library/vstudio/ms788747.aspx 需求,自定义ListView中的滚动条 这岂不是很简单?刷刷刷写完了, ...
- 【QT】error: macro "SIGNAL" passed 3 arguments, but takes just 1
error: macro "SIGNAL" passed 3 arguments, but takes just 1 错误原因: "SIGNAL"后面括号掉了. ...
- 细说Python2.x与3.x版本区别
Python的3.0版本,常被称为Python 3000,或简称Py3k.相对于Python的早期版本,这是一个较大的升级. 为了不带入过多的累赘,Python 3.0在设计的时候没有考虑向下相容 ...
- it码农之心灵鸡汤(一)
到底该怎么面对工作,到底怎么面临人生.到底怎么面临青春,对于打工的人来说这些一直都是心中一直无法解惑的谜团. 对于人们怎样看待工作,以前华为创始人任正非说过:非常多人问我,来公司工作有没有双休?需不须 ...