permissions.py源码分析

SAFE_METHODS = ('GET', 'HEAD', 'OPTIONS')
#GET请求,HEAD获取头部信息,OPTIONS获取可用请求类型设置为安全方法
#POST,PUT,PATCH,DELETE都会修改数据,没有加到这个元组

  

@six.add_metaclass(BasePermissionMetaclass)
class BasePermission(object):
"""
A base class from which all permission classes should inherit.
""" def has_permission(self, request, view):
"""
Return `True` if permission is granted, `False` otherwise.
"""
return True def has_object_permission(self, request, view, obj):
"""
Return `True` if permission is granted, `False` otherwise.
"""
return True
#所有权限类都该继承它
#两个方法,has_perm,has_obj_perm

  

class AllowAny(BasePermission):
"""
Allow any access.
This isn't strictly required, since you could use an empty
permission_classes list, but it's useful because it makes the intention
more explicit.
""" def has_permission(self, request, view):
return True
#允许任何访问
#不是严格需要,因为可以使用空的权限类,但它会使代码更清晰

  

class IsAuthenticated(BasePermission):
"""
Allows access only to authenticated users.
""" def has_permission(self, request, view):
return bool(request.user and request.user.is_authenticated)
#只要认证用户允许访问
#重写了has_permission方法,返回(用户为真)和(用户被认证为真)的与值

  

class IsAdminUser(BasePermission):
"""
Allows access only to admin users.
""" def has_permission(self, request, view):
return bool(request.user and request.user.is_staff)
#只允许管理员用户访问
#is_staff是users表里的一个字段

  

class IsAuthenticatedOrReadOnly(BasePermission):
"""
The request is authenticated as a user, or is a read-only request.
""" def has_permission(self, request, view):
return bool(
request.method in SAFE_METHODS or
request.user and
request.user.is_authenticated
)
#认证用户的请求,或者只读请求
#请求方法在SAFE_METHODS 这个元组里则返回True
#请求用户为认证用户也返回True

  

class DjangoModelPermissions(BasePermission):
"""
The request is authenticated using `django.contrib.auth` permissions.
See: https://docs.djangoproject.com/en/dev/topics/auth/#permissions It ensures that the user is authenticated, and has the appropriate
`add`/`change`/`delete` permissions on the model. This permission can only be applied against view classes that
provide a `.queryset` attribute.
""" # Map methods into required permission codes.
# Override this if you need to also provide 'view' permissions,
# or if you want to provide custom permission codes.
perms_map = {
'GET': [],
'OPTIONS': [],
'HEAD': [],
'POST': ['%(app_label)s.add_%(model_name)s'],
'PUT': ['%(app_label)s.change_%(model_name)s'],
'PATCH': ['%(app_label)s.change_%(model_name)s'],
'DELETE': ['%(app_label)s.delete_%(model_name)s'],
} authenticated_users_only = True def get_required_permissions(self, method, model_cls):
"""
Given a model and an HTTP method, return the list of permission
codes that the user is required to have.
"""
kwargs = {
'app_label': model_cls._meta.app_label,
'model_name': model_cls._meta.model_name
} if method not in self.perms_map:
raise exceptions.MethodNotAllowed(method) return [perm % kwargs for perm in self.perms_map[method]] def _queryset(self, view):
assert hasattr(view, 'get_queryset') \
or getattr(view, 'queryset', None) is not None, (
'Cannot apply {} on a view that does not set '
'`.queryset` or have a `.get_queryset()` method.'
).format(self.__class__.__name__) if hasattr(view, 'get_queryset'):
queryset = view.get_queryset()
assert queryset is not None, (
'{}.get_queryset() returned None'.format(view.__class__.__name__)
)
return queryset
return view.queryset def has_permission(self, request, view):
# Workaround to ensure DjangoModelPermissions are not applied
# to the root view when using DefaultRouter.
if getattr(view, '_ignore_model_permissions', False):
return True if not request.user or (
not request.user.is_authenticated and self.authenticated_users_only):
return False queryset = self._queryset(view)
perms = self.get_required_permissions(request.method, queryset.model) return request.user.has_perms(perms)
#使用django.contrib.auth权限认证请求
#确保用户被认证,并且在model上拥有合适的add,change,delete的权限
#只有在有queryset属性的类视图上使用
#
#perms_map
#映射方法到权限码
#如果要提供view权限,或者自定义权限码,重写它
#每个method对应一个列表,格式是app_label.codename,比如cmdb.add_gameid
#
#get_required_permissions
#输入一个model和http方法
#如果method没有在perms_map映射表,则抛出错误
#返回权限列表
#
#_queryset
#检查视图中有没有queryset属性或者get_queryset方法,没有则报错。
#
#has_permission
#检查有没有权限
#如果view中定义_ignore_model_permissions则直接返回True
#如果账户没有认证,则返回False
#将用户拥有的权限返回

  

class DjangoModelPermissionsOrAnonReadOnly(DjangoModelPermissions):
"""
Similar to DjangoModelPermissions, except that anonymous users are
allowed read-only access.
"""
authenticated_users_only = False
#继承自DjangoModelPermissions
#改变一个参数,允许匿名用户的只读访问

  

全局设置

    'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.AllowAny',
),
#在rest_framework/settings.py中,默认的权限配置AllowAny REST_FRAMEWORK = {
...
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.DjangoModelPermissions',
),
}
#可以在项目的settings中,修改为DjangoModelPermissions,这是最常用的

  

局部设置

  只允许认证用户访问,只对这个viewset生效

from rest_framework.permissions import IsAuthenticated

class SvrconfigViewSet(viewsets.ReadOnlyModelViewSet):
"""
retrieve:
返回指定信息
list:
返回列表
"""
queryset = Svrconfig.objects.all()
serializer_class = SvrconfigSerializer
permission_classes = (IsAuthenticated,)
#给一个视图集设置权限,只有认证用户可以访问
#没有用户信息,会出现401错误

  

get权限

在DjangoModelPermissions中,默认get是不需要权限的,但业务中的查看一般是需要权限的所以需要重写。

project/permissions.py

#重建权限映射
from rest_framework.permissions import DjangoModelPermissions class Permissions(DjangoModelPermissions): perms_map = {
'GET': ['%(app_label)s.view_%(model_name)s'],
'OPTIONS': [],
'HEAD': [],
'POST': ['%(app_label)s.add_%(model_name)s'],
'PUT': ['%(app_label)s.change_%(model_name)s'],
'PATCH': ['%(app_label)s.change_%(model_name)s'],
'DELETE': ['%(app_label)s.delete_%(model_name)s'],
}

  

settings.py

REST_FRAMEWORK = {
...
'DEFAULT_PERMISSION_CLASSES': (
'project.permissions.Permissions',
),
}

  

  

DRF教程9-权限的更多相关文章

  1. revel框架教程之权限控制

    Go语言实战 - revel框架教程之权限控制 一个站点上面最基本都会有三种用户角色,未登录用户.已登录用户和管理员.这一次我们就来看看在revel框架下如何进行权限控制. 因为revel是MVC结构 ...

  2. DRF 认证、权限、限制

    DRF 认证.权限.限制   认证: 定义一个用户表和一个保存用户的Token表 # ======================day96======================= class ...

  3. DRF内置权限组件之自定义权限管理类

    DRF内置权限组件permissions 权限控制可以限制用户对于视图的访问和对于具体数据对象的访问. 在执行视图的dispatch()方法前,会先进行视图访问权限的判断 在通过get_object( ...

  4. drf 教程

    1, 序列化 Serialization 创建一个新环境 在做其他事之前,我们会用virtualenv创建一个新的虚拟环境.这将确保我们的包配置与我们正在工作的其他项目完全隔离. virtualenv ...

  5. drf 认证、权限、限流、过滤、排序、分页器

    认证Authentication 准备工作:(需要结合权限用) 1. 需要使用到登陆功能,所以我们使用django内置admin站点并创建一个管理员. python manage.py creates ...

  6. django框架-DRF工程之权限功能

    1.相对于flask,原生而言django,DRF做的则更加的合理化,想要给予用户相应的权限,首先需要在settings中进行配置 REST_FRAMEWORK = { 'DEAFAULT_PERMI ...

  7. 06.drf(django)的权限

    默认配置已经启用权限控制 settings 'django.contrib.auth', 默认 migrate 会给每个模型赋予4个权限,如果 ORM 类不托管给django管理,而是直接在数据库中建 ...

  8. drf认证、权限、限流

    认证Authentication(5星) 认证逻辑及编写步骤 逻辑 认证类:用来校验用户是否登录,如果登录了,继续往下走,如果没有登录,直接返回 编写步骤 -第一步:写一个类,继承BaseAuthen ...

  9. Go语言实战 - revel框架教程之权限控制

    一个站点上面最基本都会有三种用户角色,未登录用户.已登录用户和管理员.这一次我们就来看看在revel框架下如何进行权限控制. 因为revel是MVC结构的,每一个url其实都会映射到一个具体的Cont ...

  10. [django]drf知识点梳理-权限

    用户 - 权限 - 资源 (拥有) (绑定) django权限机制能够约束用户行为,控制页面的显示内容,也能使API更加安全和灵活:用好权限机制,能让系统更加强大和健壮 django权限控制 Djan ...

随机推荐

  1. c语言学习的第11天 指针

    #include<stdio.h> int main(void) { int * p; int i=3; int j; p=&i; j=*p; printf("i=%d, ...

  2. 在线接口管理工具-eoapi

    为了方便和前端沟通,临时在局域网搭建了一个接口管理工具,查了一些资料都说eoapi不错,那就试了一下: 1.安装 要在服务器或者自己的电脑,准备web环境,Linux可以是Apache/nginx , ...

  3. 【MFC】动态创建CMFCToolbar图标不显示问题

    最近遇到一个问题,需要动态的从xml文件读取一系列图标文件,加载到一个toolbar中,由于使用的是vs2008 with sp1 feature pack,自然想到用CMFCToolbar来做,思路 ...

  4. codeforces 660A A. Co-prime Array(水题)

    题目链接: A. Co-prime Array time limit per test 1 second memory limit per test 256 megabytes input stand ...

  5. 损失函数(Loss function) 和 代价函数(Cost function)

    1损失函数和代价函数的区别: 损失函数(Loss function):指单个训练样本进行预测的结果与实际结果的误差. 代价函数(Cost function):整个训练集,所有样本误差总和(所有损失函数 ...

  6. WPF Background的设置有坑

    今天帮忙同事解决在后台绑定时,动态更改控件(Grid)的Background. 有个陷阱,C#有2个命名空间有Brush和Color, 分别为System.Drawing和System.Window. ...

  7. UDK性能优化

    转自:http://www.cnblogs.com/NEOCSL/p/3320510.html 优化问题有很多内容可讲,涉及林林总总.今天我总结一下优化注意的地方. 1.从AnimTree和Skele ...

  8. chromium浏览器开发系列第四篇:如何调试最新chromium

    接二连三的事情,时间比较紧张,但是还是没有把这个系列的文章丢掉,因为这也是对自己知识的总结吧.提倡大家多写写,以后再看的时候会有种莫名的小激动. 上周写的是chromium的目录结构,好像大家不太感兴 ...

  9. 塞尔达:旷野之息个人对比上古卷轴V:天际

    上古卷轴5是我之前玩过最优秀的作品.玩塞尔达的时候就有跟上古卷轴5比对,真的都是神作.两个游戏的自由度都是真的高. 主线剧情上,老滚5印象不深了,当时就知道战斗,只记住了开头砍头现场,还有奥杜因这个龙 ...

  10. Linux下磁盘加密luks使用

    使用luks加密磁盘,磁盘需要映射才可以挂载,映射的时候需要输入密码验证.luks相对于是对硬盘上了一把锁,要想打开就得有相应的钥匙,如果打开了就可以随意操作了,和普通硬盘一样. 使用方法如下: 0. ...