
上图为验证流程图。
面向对象知识:子类继承 父类,调用方法的时候:优先去自己里面找有没有这个方法,有就执行自己的只有当自己里面没有这个方法的时候才会去父类找。
用户访问我们的页面的时候,如何来进行验证呢?前篇文章我们已经顺利的实现了token,并将将token返回给了用户,现在我们来模拟用户访问,如果用访问时,携带来的token在我们的数据库里,我们就返回具体的数据给用户查看,如果用户没有带来正确的token,我们就返回未登陆或没有权限的提示。为了实现这个功能,我们这样:
第一步,我们新建一个字典,来模拟数据库里的数据(省点时间,完全可以建一张数据表,存入具体数据来测试)
ORDER_DICT = {
1:{
'name':'apple',
'price':15
},
2:{
'name':'dog',
'price':100
}
}
第二步,我们新建一个类视图,用于显示用户访问的时候,显示具体的数据
from django.http import JsonResponse
from rest_framework.views import APIView
class OrderView(APIView):
'''显示具体的数据'''
#get请求
def get(self,request,*args,**kwargs):
ret = {'code':1000,'msg':None,'data':None}#定义一个返回字典 1000表示正常,默认错误信息和返回内容为空
try:
ret['data'] = ORDER_DICT #无异常就返回字典的内容
except Exception as e:
pass
return JsonResponse(ret)
上面的代码,并没有实现权限的认证,那么我们要如何实现访问权限认证呢?
首先,我们新建一个权限处理类:
from rest_framework import exceptions #导入try的错误提示方法
from API import models #导入模型
from rest_framework.authentication import BaseAuthentication #导入权限验证的父类
我们继承这个父类
class Authentication(BaseAuthentication):
'''用于用户登陆验证'''
def authenticate(self,request):#重写 authenticate方法
token = request._request.GET.get('token')#获取url上的token
token_obj = models.UserToken.objects.filter(token=token).first() #去token表里差,是否有这个
if not token_obj:
raise exceptions.AuthenticationFailed('用户认证失败') #没有就返回错误提示
#正常就返回具体内容,在rest framework内部会将这两个字段赋值给request,以供后续操作使用
return (token_obj.user,token_obj) #元素1复制给request.user; 元素2复制给request.auth
#下面这个方法必须要这样写,保持为空就行,没有就要报错,具体原因需要看源码了
def authenticate_header(self, request):
pass
然后我们来修改一下我们第二步的哪个类视图
class OrderView(APIView):
'''显示具体的数据'''
authentication_classes = [Authentication,] #添加认证,增加了这一行
#get请求
def get(self,request,*args,**kwargs):
ret = {'code':1000,'msg':None,'data':None}#定义一个返回字典 1000表示正常,默认错误信息和返回内容为空
try:
ret['data'] = ORDER_DICT #无异常就返回字典的内容
except Exception as e:
pass
return JsonResponse(ret)
如果我们不想在每一个需要的视图都这样麻烦,添加这么一句,我们可以在settings.py里设置全局,这样就可以将局部设置改为全局设置
settings.py
#设置全局认证
REST_FRAMEWORK = {
"DEFAULT_AUTHENTICATION_CLASSES":['API.utils.auth.Authentication',] #里面写你的认证的类的路径
}
建一个url,打开POSTman测试一下,
path('api/v1/order/',OrderView.as_view()),
不带token

带token

小结:
(1)创建认证类
- 继承BaseAuthentication --->>1.重写authenticate方法;2.authenticate_header方法直接写pass就可以(这个方法必须写)
(2)authenticate()返回值(三种)
- None ----->>>当前认证不管,等下一个认证来执行
- raise exceptions.AuthenticationFailed('用户认证失败') # from rest_framework import exceptions
- 有返回值元祖形式:(元素1,元素2) #元素1复制给request.user; 元素2复制给request.auth
(3)局部使用
- authentication_classes = [BaseAuthentication,]
(4)全局使用
#设置全局认证
REST_FRAMEWORK = {
"DEFAULT_AUTHENTICATION_CLASSES":['API.utils.auth.Authentication',]
}
登陆后方可评论