教程4--认证和权限
来源:互联网 发布:php 获取系统信息 编辑:程序博客网 时间:2024/06/05 00:24
教程4–认证和权限
目前我们的API对于谁可以编辑或者删除代码段没有任何的限制。我们希望能有一些更加高级的行为来确保:
- 代码段总是能够关联到一个创建者。
- 只有认证通过的用户才能够创建代码段。
- 只有代码段的创建者才能够更新或者删除代码段。
- 没有通过认证的用户拥有只读权限。
为我们的模型添加信息
让我们给之前的Snippet
模型添加一些信息。首先,先添加一些字段。因为要关联到谁创建了代码段,所以要添加creator字段。其他字段用来存储高亮的HTML。
owner = models.ForeignKey('auth.User', related_name='snippets', on_delete=models.CASCADE)highlighted=models.TextField()
我们也需要确保当模型被保存时,使用pygments
代码高亮库来填充highlighted
字段。
我们需要一些额外的引入:
from pygments.lexers import get_lexer_by_namefrom pygments.formatters.html import HtmlFormatterfrom pygments import highlight
此时,我们可以为我们的模型添加.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 = 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)
然后,重新创建数据库:
rm -f tmp.db db.sqlite3rm -r snippets/migrationspython manage.py makemigrations snippetspython manage.py migrate
你可能想要多创建几个不同的用户用以测试,最方便的方法莫过于使用createsuperuser
命令了。
python manage.py createsuperuser
为User模型添加端点
from django.contrib.auth.models import Userclass UserSerializer(serializers.ModelSerializer): snippets = serializers.PrimaryKeyRelatedField(many=True, queryset=Snippet.objects.all()) class Meta: model = User fields = ('id', 'username', 'snippets')
我们使用了ModelSerializer,它会包含User这个Model的所有字段。但是由于’snippets’对于User来说是一个反向的关系,所以UserSerializer默认是不会包含snippets
的,我们需要自行添加。
我们也需要添加些View,但对于User来说,只读就可以了,因此我们使用ListAPIView
和RetrieveAPIView
来生成基于类的视图。
class UserList(generics.ListAPIView): queryset = User.objects.all() serializer_class = UserSerializerclass UserDetail(generics.RetrieveAPIView): queryset = User.objects.all() serializer_class = UserSerializer
最后添加上新的urls映射:
url(r'^users/$', views.UserList.as_view()), url(r'^user/(?P<pk>[0-9]+)/$', views.UserDetail.as_view())
将Users合并到Snippets中
到目前为止,如果我们创建一个代码段,还没有办法把User的信息添加到Snippet对象中去。
我们的解决方案是重写snippet视图的.perform_create()
方法,允许我们修改实例的保存方式,并且处理所有隐含在请求或者请求URL中的信息。
在SnippetList中,添加如下方法:
def perform_create(self, serializer): serializer.save(owner=self.request.user)
现在snippet的create()
方法在调用时将会传入一个owner
字段,和validated_data一起传入。
更新序列化器
现在,代码片段已经和创建他们的用户相关联。让我们来更新SnippetSerializer
。在serializers.py
中添加如下代码:
owner = serializers.ReadOnlyField(source='owner.username')
注意:请确保你在Meta中也添加了owner,
。
这个字段做了一些很有意思的事情。source
字段控制哪个属性用于填充字段,并且可以指向序列化实例的任何一个属性。而且还可以像上面一样,用点号获取,这样它会遍历给定的属性,就类似于Django的模板语言。
这里我们添加的Field是一个无类型Field——ReadOnlyField
。不同于有类型的Field,该类型的Filed只读,只用于做展示,不能用于更新。这里我们也可以使用CharField(read_only=True)
。
为视图添加权限
现在我们已经将code snippets和它们的创建者关联起来了,我们想要确保只有认证了的用户才能创建、更新和删除代码段。
REST框架提供了一套权限类,可以让我们来限制可以访问View的用户。我们当前的案例中,我们是希望没认证的用户只能读取,认证的可以修改,所以应该使用IsAuthenticatedOrReadOnly
。
如何使用呢?
首先要引入permissions模块
from rest_framework import permissions
然后再SnippetList和SnippetDetail视图都加入以下语句:
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
添加登录API
此时,如果你打开浏览器,访问Snippet的API,你会发现你现在已经创建不了新的代码段了。为了能够创建代码,我们必须登录。
我们可以添加一个登录视图,通过编辑URLconfig来添加。编辑项目最顶层的urls.py
文件。
from django.conf.urls import include
在文件的结尾处添加一个pattern,用于登录和注销。
urlpatterns += [ url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),]
现在如果你现在再次打开浏览器,可以看到登录按钮,登陆后就可以创建或修改代码段了。
对象级权限控制
事实上,我们只是控制了认证的人拥有写权限,但是我们预期的是只有当前项的创建者才能修改或删除该值。
为了能够实现这种控制,我们需要创建一个自定义的权限。
在snippets app中,创建一个新的文件permissions.py
:
from rest_framework import permissionsclass 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_class
属性:
from snippets.permissions import IsOwnerOrReadOnly....permission_classes = (permissions.IsAuthenticatedOrReadOnly, IsOwnerOrReadOnly,)
现在,如果你重新打开浏览器,你会发现只有你创建的Snippet才会出现DELETE
或者PUT
的动作。
使用API进行验证
目前,我们没有设置任何的Authentication类,所以默认情况下是使用SessionAuthentication
和BasicAuthentication
。
当我们通过浏览器访问API,我们可以通过登录页面登录,并且浏览器的session会保存认证所必须的数据。
如果我们使用命令行交互,则必须为每一个请求都显式指定验证数据。
如果我们项要创建一个Snippet,但是又没有登录,我们会得到以下错误:
http POST http://127.0.0.1:8000/snippets/ code="print 123"{ "detail": "Authentication credentials were not provided."}
如果带上了验证信息,那么请求就能够执行成功了。
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提供了相当细粒度的权限控制了。
在下一章中,我们讲学习如何将一切联系在一起,创造出高亮代码段的HTML endpoint,并利用超链接关系提高我们API之间的关联。
- 教程4--认证和权限
- MongoDB用户认证和权限
- nutz基于shiro实现身份认证和权限认证
- mysql 的帐号认证和权限控制
- Mongodb用户和认证 权限总结
- Mongodb用户和认证 权限总结
- Mongodb用户和认证 权限总结 (转载)
- Mongodb用户和认证 权限总结
- 【Mongodb】用户和认证 权限总结
- 【Mongodb】用户和认证 权限总结
- Mongodb用户和认证 权限总结
- Mongodb用户和认证 权限总结
- 【Mongodb】用户和认证 权限总结
- MongoDB的用户、认证和权限
- Shiro的认证和权限控制
- 网站认证和授权(自定义权限)
- Django-restframework05 用户认证和权限管理
- 权限认证
- React Native三方组件之scrollable-tab-view
- Activity的四种启动模式详解
- PostgreSQL相关常用命令记录(20170324-20170324)
- SOJ 1037
- mysql中join后on、where的区别
- 教程4--认证和权限
- 利用心跳检测判断系统间的连通性
- js判断是否在iframe中
- java,Iterator用法,Guava用法
- Linux中执行shell脚本的4种方法总结
- ant使用入门
- ubuntu忘记了用户登录密码怎么办
- 将bitmap保存本地
- 27.session访问时长和步长占比本地测试