Django Rest Framework自定义身份验证+基本身份验证

时间:2015-08-19 08:44:37

标签: django authentication django-rest-framework custom-authentication

我在我的Python-Django应用程序中使用Django Rest Framework,并且正在为api使用自定义身份验证。

如果我只使用自定义身份验证方法,则工作正常。

 @authentication_classes((CustomAuthentication,  ))

但是如果我尝试进行基本身份验证和自定义身份验证,那么我的自定义身份验证永远不会执行。我的意思是,我希望如果基本身份验证失败,请尝试使用自定义身份验证。执行基本身份验证然后结束。

@authentication_classes((SessionAuthentication, BasicAuthentication, CustomAuthentication ))

可以同时使用这三种身份验证方法,并按顺序执行它们吗?

2 个答案:

答案 0 :(得分:0)

Django Rest Framework身份验证documentation明确指出:

  

身份验证方案始终定义为类列表。   REST框架将尝试对其中的每个类进行身份验证   list,并将使用return设置request.user和request.auth   成功进行身份验证的第一个类的值。

     

如果没有类进行身份验证,则request.user将设置为的实例   将设置django.contrib.auth.models.AnonymousUser和request.auth   无。

因此,只要您的第一堂课认证request.user并设置request.auth

如果您要使用CustomAuthentication return None BasicAuthentication类对CustomAuthentication进行身份验证,以便使用所有身份验证类,但用户的设置符合<div class="dynamic-data"> </div> < / p>

答案 1 :(得分:0)

@Arpit Goyal的回答使工作流程清晰。

如果您想要查看所有身份验证类,

这是您可以尝试的解决方案解决方案。我希望它可以帮到你。

@authentication_classes((AuthencationWrapper,  ))

添加AuthencationWrapper

class AuthencationWrapper(BaseAuthentication):

    authenication_classes = (
        BasicAuthentication,
        SessionAuthentication,
        CustomAuthentication,
    )

    def authenticate(self, request):
        exc = None
        ret = None
        for auth in self.authentication_classes:
            try:
                ret = auth().authenticate(request)
                # if success, we will break, else we will continue to call next one
                break
            except exceptions.AuthenticationFailed as e:
                # we only record the first failed exception
                if exc is None:
                    exc = e
                    self.first_failed_auth = auth()
        if ret is None:
            raise exc

        # one of the authentication_classes is passed
        return ret

    def authenticate_header(self, request):
        # actualy this way breaks what django-rest-framework doing now
        return self.first_failed_auth.authenticate_header(request)

        # the one follows what django-rest-framework doing now
        # choose the first authentication class header
        ## if self.authentication_classes:
        ##      return self.authentication_classes[0].authenticate_header(request)