1

Python-Django アプリで Django Rest Framework を使用しており、API にカスタム認証を使用しています。

カスタム認証方法だけを使用すると、正しく機能します。

 @authentication_classes((CustomAuthentication,  ))

しかし、基本認証とカスタム認証をこの順序で取得しようとすると、カスタム認証が実行されません。つまり、基本認証が失敗した場合は、カスタム認証を試してください。基本認証が実行され、終了します。

@authentication_classes((SessionAuthentication, BasicAuthentication, CustomAuthentication ))

この 3 つの認証方法を同時に使用し、その順序で実行することはできますか?

4

2 に答える 2

0

Django Rest Framework認証ドキュメントには、次のように明確に記載されています。

認証方式は、常にクラスのリストとして定義されます。REST フレームワークはリスト内の各クラスで認証を試み、認証に成功した最初のクラスの戻り値を使用して request.user と request.auth を設定します。

どのクラスも認証しない場合、request.user は django.contrib.auth.models.AnonymousUser のインスタンスに設定され、request.auth は None に設定されます。

したがって、最初のクラスが認証され、設定されるたびrequest.userrequest.auth

すべての認証クラスが使用されるようにCustomAuthenticationクラスreturn Noneで認証したいが、ユーザーはあなたのように設定されている場合BasicAuthenticationCustomAuthentication

于 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 に答える