1

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

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

 @authentication_classes((CustomAuthentication,  ))

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

@authentication_classes((SessionAuthentication, BasicAuthentication, CustomAuthentication ))

是否可以同时拥有这三种身份验证方法,并按顺序执行它们?

4

2 回答 2

0

Django Rest Framework身份验证文档清楚地说明了这一点:

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

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

因此,每当您的第一堂课进行身份验证request.userrequest.auth设置时。

如果您想使用您的CustomAuthenticationreturn None进行身份验证,BasicAuthentication以便使用您的所有身份验证类,但用户是根据您的CustomAuthentication

于 2015-08-19T09:07:06.117 回答
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)
于 2015-08-19T10:02:02.373 回答