I am using rest_framework_simplejwt
to authenticate my users but, in some views i need to ignore it, because these are public views. i want to check the token into view flow. The expected behaviour is:
In public view
Actually rest_framework_simplejwt
checks token and raise 401
if token is invalid or expired...
I tried disabling authentication_classes
within APIView like this:
class SpecificProductApi(APIView):
def get_authenticators(self):
if self.request.method == 'GET':
self.authentication_classes = []
return super(SpecificProductApi, self).get_authenticators()
but if i disable it before enter GET APIView
method, i can't do if reques.user.is_authenticated:
because I disabled the token :(
Exists a way to enable entering to api http method and check users manually into view? thanks
Have a very similar problem. To create public endpoints you are forced to override the authenticators, or else you will return 401/403 on expired/missing token.
However, a public endpoint does not mean that it should not have authentication. Rather it should have one response for no-auth / expired-auth and another for valid auth.
I don't know if this is the "correct" way, but this is what I came up with facing the same problem.
Override the authenticators as you have done, and add an additional method to validate the authenticators in your view.
For example:
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.