Django Rest Framework 避免身份验证 JWT

Jho*_*anz 4 django python-3.x django-rest-framework jwt-auth django-rest-framework-simplejwt

我正在使用rest_framework_simplejwt对我的用户进行身份验证,但是在某些视图中我需要忽略它,因为这些是公共视图。我想将令牌检查到视图流中。预期的行为是:

在公众视野中

  • 避免令牌验证:如果有过期或无效的令牌,请忽略它并让我在 APIView 中验证它

实际上rest_framework_simplejwt检查令牌并401在令牌无效或过期时引发......

我尝试authentication_classes在 APIView 中像这样禁用:

class SpecificProductApi(APIView):

    def get_authenticators(self):
        if self.request.method == 'GET':
            self.authentication_classes = []
        return super(SpecificProductApi, self).get_authenticators()
Run Code Online (Sandbox Code Playgroud)

但是如果我在输入GET APIView方法之前禁用它,我不能这样做,if reques.user.is_authenticated:因为我禁用了令牌:(

是否存在启用进入 api http 方法并手动检查用户查看的方法?谢谢

小智 7

我通过添加来完成它 authentication_classes = []

from rest_framework import permissions

class SpecificProductApi(APIView):
    permission_classes = [permissions.AllowAny]
    authentication_classes = []
Run Code Online (Sandbox Code Playgroud)


Nem*_*man 5

您可以简单地authentication_classes = []在视图中使用,但这始终会绕过 JWT 身份验证,即使存在带有令牌的有效 Authorization-header 也是如此。您最好按如下方式扩展 JWTAuthentication 类(类似于 Jhon Edwin Sanz Gonzalez 的评论):

from rest_framework_simplejwt.authentication import JWTAuthentication
from rest_framework_simplejwt.exceptions import InvalidToken


class JWTAuthenticationSafe(JWTAuthentication):
    def authenticate(self, request):
        try:
            return super().authenticate(request=request)
        except InvalidToken:
            return None
Run Code Online (Sandbox Code Playgroud)

然后authentication_classes = [JWTAuthenticationSafe]在您的视图中使用。


Jam*_*mes 1

有一个非常相似的问题。要创建公共端点,您必须覆盖身份验证器,否则您将在令牌过期/丢失时返回 401/403。

但是,公共端点并不意味着它不应该进行身份验证。相反,它应该对无身份验证/过期身份验证有一个响应,对有效身份验证有另一个响应。

我不知道这是否是“正确”的方法,但这是我面对同样的问题时想到的。

像您所做的那样覆盖身份验证器,并添加一个附加方法来验证视图中的身份验证器。

例如:

class SomeApiView(APIView):
    def get_authenticators(self):
        # Override standard view authenticators.
        # Public endpoint, no auth is enforced.
        return []

    def get_auth(self):
        # Return a generator of all authenticators.
        return (auth() for auth in self.authentication_classes)

    def get_auth_detail(self, request):
        # Evaluate each authenticator and return the first valid authentication.
        for auth in self.get_auth():
            # You probably need try / except here to catch authenticators 
            # that are invalid (403/401) in the case of multiple authentication 
            # classes--such as token auth, session auth, etc...
            auth_detail = auth.authenticate(request)
            if auth_detail:
                return auth_detail

        return None, None

    def post(self, request):
        # Returns a tuple of (User, JWT), can be (None, None)
        user, jwt = self.get_auth_detail(request)  

        # Do your magic based on user value.
        if user:
            # User is authenticated.
        else:
            # User is anon / not-authenticated.
Run Code Online (Sandbox Code Playgroud)