自写认证程序,模拟用户访问认证(判断携带token与否)


发布时间:2019-03-23 17:41    作者: Uncle Hui   已过去:1 年   阅读总量:702 已被赞:3


 

上图为验证流程图。

面向对象知识:子类继承 父类,调用方法的时候:优先去自己里面找有没有这个方法,有就执行自己的只有当自己里面没有这个方法的时候才会去父类找。

 

用户访问我们的页面的时候,如何来进行验证呢?前篇文章我们已经顺利的实现了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',]
}

点赞

3




登陆后方可评论