rest_framework组件
认证源码流程图:
APIView类 第一步class OrderView(APIView):点击APIView 第二步def dispatch(self, request, *args, **kwargs): 找到self.initial(request, *args, **kwargs),点击initial 第三步def initial(self, request, *args, **kwargs): 找到self.perform_authentication(request)(进行认证) 点击perform_authentication 第四步def perform_authentication(self, request): request.user Request类 第五步同上def dispatch(self, request, *args, **kwargs): 找到request = self.initialize_request(request, *args, **kwargs) 点击initialize_request 第六步def initialize_request(self, request, *args, **kwargs): 找到return Request,点击Request 第七步class Request(object): 找到 @property def user(self):(获取认证对象,进行一步步认证) 找到return self._user 第八步还是@property def user(self):里面 找到self._authenticate()点击_authenticate 第九步def _authenticate(self): (循环所有对象,执行认证方法) Authtication自定义认证类(自己写了认证方法,就用自己的) 第十步def authenticate(self, request): 报错:(返回元祖(user对象,token对象)) class OrderView(APIView):或class AuthView(APIView):等订单 第十一步执行各个订单的def post: 或def get:等方法
认证组件
局部认证
在需要认证的视图类里加上authentication_classes = [认证组件1类名,认证组件2类名....]
示例如下:
seralizers.py
1
2
3
4
5
6
7
|
from
rest_framework
import
serializers
from
app01
import
models
class
PublishSerializers(serializers.ModelSerializer):
class
Meta:
model
=
models.Publish
fields
=
'__all__'
|
auth.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
from
rest_framework.authentication
import
BaseAuthentication
from
rest_framework
import
exceptions
from
app01
import
models
class
TokenAuth(BaseAuthentication):
def
authenticate(
self
,request):
'''函数名必须叫authenticate'''
# 验证条件根据需求设置(此示例为需要有token值)
token
=
request.GET.get(
'token'
)
token_obj
=
models.Token.objects.
filter
(token
=
token).first()
if
not
token_obj:
# 如果验证失败,需要跑出AuthenticationFailed错误
raise
exceptions.AuthenticationFailed(
"验证失败!"
)
else
:
user
=
token_obj.user
# 如果验证成功,需要返回一个元组,分别是用户以及验证类的实例对象,然后内部会赋值给request.user和request.auth
return
user.username,token_obj
|
views.py
1
2
3
4
5
6
7
8
9
10
|
from
rest_framework
import
viewsets
from
app01.auth
import
TokenAuth
class
PublishViewSet(viewsets.ModelViewSet):
# 在这里配置authentication_classes
# 注意,值为一个列表,可以放多个认证组件类名
authentication_classes
=
[TokenAuth]
queryset
=
models.Publish.objects.
all
()
serializer_class
=
serializer.PublishSerializers
|
全局认证
在setting.py里配置如下:
1
2
3
|
REST_FRAMEWORK
=
{
"DEFAULT_AUTHENTICATION_CLASSES"
: [
"app01.auth.TokenAuth"
,]
}
|
这样配置之后,每个视图类都要经过认证成功之后才能执行下一步,
如果有某些方法不需要认证,如login函数,则需要在login函数中单独加入一个配置属性:
1
|
authentication_classes
=
[]
#自己的类里有的话就调用此类的配置,为空既什么都不做
|
权限认证
局部认证
permission.py
1
2
3
4
5
6
7
8
9
10
11
12
13
|
from
app01
import
models
class
VipPermission():
def
has_permission(
self
,request,view):
# 经过认证组件之后将用户名赋值给了request.user
# 这里可以直接取到
username
=
request.user
user
=
models.User.objects.
filter
(username
=
username).first()
# 如果用户的vip值为1,即为True,则通过认证,否则return False
if
user.vip:
return
True
else
:
return
False
|
views.py
1
2
3
4
5
6
7
8
9
|
from
rest_framework
import
viewsets
from
app01.auth
import
TokenAuth
from
app01.permission
import
VipPermission
class
PublishViewSet(viewsets.ModelViewSet):
authentication_classes
=
[TokenAuth]
permission_classes
=
[VipPermission]
queryset
=
models.Publish.objects.
all
()
serializer_class
=
serializer.PublishSerializers
|
这个时候如果登录用户是vip,则会继续执行下一步,如果是普通用户,则会返回错误信息,如下:
1
|
{
"detail"
:
"You do not have permission to perform this action."
}
|
如果需要自定义错误信息,只需要在类里定义一个message属性即可,如下:
1
|
message
=
"只有超级用户才能访问"
|
全局认证
1
2
3
4
5
6
|
REST_FRAMEWORK
=
{
# 认证组件
"DEFAULT_AUTHENTICATION_CLASSES"
: [
"app01.auth.TokenAuth"
,],
# 权限组件
"DEFAULT_PERMISSION_CLASSES"
: [
"app01.permission.VipPermission"
,],
}
|
频率认证
局部认证
格式如下:
1
2
3
4
5
6
7
8
9
|
class
VisitRateThrottle(
object
):
def
allow_request(
self
,request,view):
# 要求访问站点的频率不能超过每分钟20次等等
if
1
:
# 如果在限制之内,则返回True
return
True
else
:
return
False
|
然后在需要进行限制的视图类中加入如下配置:
1
|
throttle_classes
=
[VisitRateThrottle]
|