django rest framework之部分组件

认证

  在这里,笔者将登录与认证归一起,具体代码如下

  视图函数

def md5(user):#用账户当参数
    '''生成随机码'''
    import time
    import hashlib

    c_time = str(time.time())
    m = hashlib.md5(bytes(user,encoding='utf-8'))
    m.update(bytes(c_time,encoding='utf-8'))
    return m.hexdigest()


class AuthView(APIView):
    authentication_classes = [ ]

    def post(self,request,*args,**kwargs):#选择method请求方式
        ret = {'code':1000,'msg':None}
        try:
            username = request._request.POST.get('username')
            password = request._request.POST.get('password')
            obj = UserInfo.objects.filter(username=username,password=password).first()
            if not obj:
                ret['code'] = 1001
                ret['msg'] = '账号或者密码错误!'
            token = md5(username)
            print(token)
            models.UserToken.objects.update_or_create(user=obj,defaults={'token':token})#新建或者修改数据
            ret['msg'] = '欢迎登陆!'
            ret['token'] = token
        except Exception as e:
            pass
        return JsonResponse(ret)


class OrderView(APIView):

    # authentication_classes = [Authtication,]#局部使用
    def get(self,request,*args,**kwargs):
        print(request.user)
        print(request.auth)
        ret = {'code':1000,"msg":'ok','data':None}
        try:
            ret['data'] = ORDER_DICT
        except Exception as e:
            pass
        return JsonResponse(ret)

  为了规范,将认证放在单独的文件下:

  

  代码如下:

class Authtication(BaseAuthentication):#继承父类header就可以省略,因为父类里面有
    def authenticate(self,request):
        token = request._request.GET.get('token')
        token_obj = UserToken.objects.filter(token=token).first()
        if not token_obj:
            raise exceptions.AuthenticationFailed('用户认证失败!')
        #drf会将两个字段的值赋值给request,以供后续使用
        return (token_obj.user,token_obj)

    # def authenticate_header(self,request):
    #     pass

  由于drf的机制,主要是列表生成式:在全局进行认证我们可以在配置文件中这么写:

REST_FRAMEWORK = {
    "DEFAULT_AUTHENTICATION_CLASSES":["api.utils.auth.Authtication",]    #这里必须是列表,否则会报错'type' object is not iterable
}

  接下来是源码的个人解读:

用户认证源码流程

1.请求进来之后,先在自己的类中寻找dispatch方法,由于我们没有自己定义,所以找到父类ApiView中的dispatch开始执行方法

2.进入dispatch方法之后,对request进行封装,request不再是原生的request(如果要使用可以用request._request调用)
    封装的时候执行了一个authenticators=self.get_authenticators()方法,通过列表生成式实例化对象

3.封装完request之后,开始执行initial方法,其中我们的认证是self.perform_authentication(request)这个方法实现的

4.在三中的方法里面执行了request.user

5.然后执行self._authenticate()方法,主要用途是循环所有的authentication对象,执行所有authentication()方法

6.其实在这一步的时候我们已经可以用我们自己定义的类进行认证了
    ,执行self._authenticate()方法时,抛出异常会被捕捉,具体内容如图 pic
    如果抛出错误,会继续抛出错误,也就是意味着会继续执行列表内的认证方法

7.通过认证之后,开始执行我们自己的get post等方法

  

权限

节流

猜你喜欢

转载自www.cnblogs.com/swearBM/p/10447638.html
今日推荐