Django Rest Framework源码剖析(二)-----权限
<table style="height: 30px; background-color: #afeeee; width: 1266px; ; width: 1266px;" border="0"> |
1.在django 项目下新建立目录utils,并建立permissions.py,添加权限控制:
2.在订单视图中使用
urls.py
url(r</span><span style="color: #800000;">'</span><span style="color: #800000;">^api/v1/auth</span><span style="color: #800000;">'</span><span style="color: #000000;">,views.AuthView.as_view()),url(r</span><span style="color: #800000;">'</span><span style="color: #800000;">^api/v1/order</span><span style="color: #800000;">'</span><span style="color: #000000;">,views.OrderView.as_view()),]</span></pre>
models.py
user_type_choice =<span style="color: #000000;"> (
(1,<span style="color: #800000;">"<span style="color: #800000;">普通用户<span style="color: #800000;">"<span style="color: #000000;">),(2,<span style="color: #800000;">"<span style="color: #800000;">会员<span style="color: #800000;">"<span style="color: #000000;">),)
user_type = models.IntegerField(choices=<span style="color: #000000;">user_type_choice)
username = models.CharField(max_length=32,unique=<span style="color: #000000;">True)
password = models.CharField(max_length=64<span style="color: #000000;">)
<span style="color: #0000ff;">class<span style="color: #000000;"> UserToken(models.Model):
user = models.OneToOneField(to=<span style="color: #000000;">UserInfo)
token = models.CharField(max_length=64)
3.验证:订单业务同样使用user_type=1的用户进行验证,这里使用工具postman发送请求验证,结果如下:证明我们的权限生效了。
dispatch()
<span style="color: #0000ff;">try</span><span style="color: #000000;">:
</span><span style="color: #008000;">#</span><span style="color: #008000;">2.认证</span>
self.initial(request,**<span style="color: #000000;">kwargs)
</span><span style="color: #008000;">#</span><span style="color: #008000;"> Get the appropriate handler method</span>
<span style="color: #0000ff;">if</span> request.method.lower() <span style="color: #0000ff;">in</span><span style="color: #000000;"> self.http_method_names:
handler </span>=<span style="color: #000000;"> getattr(self,request.method.lower(),self.http_method_not_allowed)
</span><span style="color: #0000ff;">else</span><span style="color: #000000;">:
handler </span>=<span style="color: #000000;"> self.http_method_not_allowed
response </span>= handler(request,**<span style="color: #000000;">kwargs)
</span><span style="color: #0000ff;">except</span><span style="color: #000000;"> Exception as exc:
response </span>=<span style="color: #000000;"> self.handle_exception(exc)
self.response </span>= self.finalize_response(request,response,**<span style="color: #000000;">kwargs)
</span><span style="color: #0000ff;">return</span> self.response</pre>
2.执行inital方法,initial方法中执行perform_authentication则开始进行认证
</span><span style="color: #008000;">#</span><span style="color: #008000;"> Perform content negotiation and store the accepted info on the request</span>
neg =<span style="color: #000000;"> self.perform_content_negotiation(request)
request.accepted_renderer,request.accepted_media_type </span>=<span style="color: #000000;"> neg
</span><span style="color: #008000;">#</span><span style="color: #008000;"> Determine the API version,if versioning is in use.</span>
version,scheme = self.determine_version(request,**<span style="color: #000000;">kwargs)
request.version,request.versioning_scheme </span>=<span style="color: #000000;"> version,scheme
</span><span style="color: #008000;">#</span><span style="color: #008000;"> Ensure that the incoming request is permitted</span>
<span style="color: #008000;">#</span><span style="color: #008000;">4.实现认证</span>
<span style="color: #000000;"> self.perform_authentication(request)
<span style="color: #000000;"> self.check_permissions(request)
self.check_throttles(request)
3.当执行完perform_authentication方法认证通过时候,这时候就进入了本篇文章主题--权限(check_permissions方法),下面是check_permissions方法源码:
4.从上源码中我们可以看出,perform_authentication方法中循环get_permissions结果,并逐一判断权限,所以需要分析get_permissions方法返回结果,以下是get_permissions方法源码:
5.get_permissions方法中寻找权限类是通过self.permission_class字段寻找,和认证类一样默认该字段在全局也有配置,如果我们视图类中已经定义,则使用我们自己定义的类。
</span><span style="color: #008000;">#</span><span style="color: #008000;"> The following policies may be set at either globally,or per-view.</span>
renderer_classes =<span style="color: #000000;"> api_settings.DEFAULT_RENDERER_CLASSES
parser_classes </span>=<span style="color: #000000;"> api_settings.DEFAULT_PARSER_CLASSES
authentication_classes </span>=<span style="color: #000000;"> api_settings.DEFAULT_AUTHENTICATION_CLASSES
throttle_classes </span>=<span style="color: #000000;"> api_settings.DEFAULT_THROTTLE_CLASSES
<span style="color: #ff6600;"> permission_classes
<span style="color: #ff6600;">=<span style="color: #000000;"><span style="color: #ff6600;"> api_settings.DEFAULT_PERMISSION_CLASSES #权限控制content_negotiation_class =<span style="color: #000000;"> api_settings.DEFAULT_CONTENT_NEGOTIATION_CLASS
metadata_class =<span style="color: #000000;"> api_settings.DEFAULT_METADATA_CLASS
versioning_class = api_settings.DEFAULT_VERSIONING_CLASS
6.承接check_permissions方法,当认证类中的has_permission()方法返回false时(也就是认证不通过),则执行self.permission_denied(),以下是self.permission_denied()源码:
7.认证不通过,则至此django rest framework的权限源码到此结束,相对于认证源码简单一些。
<span style="color: #0000ff;">class<span style="color: #000000;"> AllowAny(BasePermission) <span style="color: #008000;">#<span style="color: #008000;">#基于django的认证权限,官方示例
<span style="color: #0000ff;">class<span style="color: #000000;"> IsAuthenticated(BasePermission):
<span style="color: #008000;">#<span style="color: #008000;">#基于django admin权限控制
<span style="color: #0000ff;">class<span style="color: #000000;"> IsAdminUser(BasePermission)
<span style="color: #008000;">#<span style="color: #008000;">#也是基于django admin
<span style="color: #0000ff;">class<span style="color: #000000;"> IsAuthenticatedOrReadOnly(BasePermission)
.....
- 继承BasePermission类(推荐)
- 重写has_permission方法
- has_permission方法返回True表示有权访问,False无权访问
2.配置:
permission_classes =<span style="color: #000000;"> [MyPremission,] <span style="color: #008000;">#<span style="color: #008000;">##优先级
单一视图>全局配置
(编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!