0
votes

I'm building an api where users have to be logged in to see the content with django, and django rest framework.

Using 'rest_framework.permissions.IsAuthenticated' and rest_framework.authentication.TokenAuthentication as it says in the documentation.

Settings.py

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
    ),
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.TokenAuthentication',
    ),
}

and it works perfectly, it does not allow to anonymous users see the contents (endpoints, views etc... ), but the problem is that it responds with an error 500 and not 401 Unauthorized as it should.

i get this exeption when I make a request without any token:

TypeError: int() argument must be a string, a bytes-like object or a number, not 'AnonymousUser'

Does anyone know what can be done for the IsAuthenticated and TokenAuthentication permissions to return 401 and not 500?

full error stack:

File "/usr/local/lib/python3.6/site-packages/django/core/handlers/exception.py", line 41, in inner
web_1  |     response = get_response(request)
web_1  |   File "/usr/local/lib/python3.6/site-packages/django/core/handlers/base.py", line 187, in _get_response
web_1  |     response = self.process_exception_by_middleware(e, request)
web_1  |   File "/usr/local/lib/python3.6/site-packages/django/core/handlers/base.py", line 185, in _get_response
web_1  |     response = wrapped_callback(request, *callback_args, **callback_kwargs)
web_1  |   File "/usr/local/lib/python3.6/site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view
web_1  |     return view_func(*args, **kwargs)
web_1  |   File "/usr/local/lib/python3.6/site-packages/rest_framework/viewsets.py", line 95, in view
web_1  |     return self.dispatch(request, *args, **kwargs)
web_1  |   File "/usr/local/lib/python3.6/site-packages/rest_framework/views.py", line 494, in dispatch
web_1  |     response = self.handle_exception(exc)
web_1  |   File "/usr/local/lib/python3.6/site-packages/rest_framework/views.py", line 454, in handle_exception
web_1  |     self.raise_uncaught_exception(exc)
web_1  |   File "/usr/local/lib/python3.6/site-packages/rest_framework/views.py", line 482, in dispatch
web_1  |     self.initial(request, *args, **kwargs)
web_1  |   File "/usr/local/lib/python3.6/site-packages/rest_framework/views.py", line 400, in initial
web_1  |     self.check_permissions(request)
web_1  |   File "/usr/local/lib/python3.6/site-packages/rest_framework/views.py", line 333, in check_permissions
web_1  |     if not permission.has_permission(request, self):
web_1  |   File "/qr/qr/permissions.py", line 39, in has_permission
web_1  |     user_company = str(CustomUser.objects.get(user=request.user).seat.company.id)
web_1  |   File "/usr/local/lib/python3.6/site-packages/django/db/models/manager.py", line 85, in manager_method
web_1  |     return getattr(self.get_queryset(), name)(*args, **kwargs)
web_1  |   File "/usr/local/lib/python3.6/site-packages/django/db/models/query.py", line 370, in get
web_1  |     clone = self.filter(*args, **kwargs)
web_1  |   File "/usr/local/lib/python3.6/site-packages/django/db/models/query.py", line 781, in filter
web_1  |     return self._filter_or_exclude(False, *args, **kwargs)
web_1  |   File "/usr/local/lib/python3.6/site-packages/django/db/models/query.py", line 799, in _filter_or_exclude
web_1  |     clone.query.add_q(Q(*args, **kwargs))
web_1  |   File "/usr/local/lib/python3.6/site-packages/django/db/models/sql/query.py", line 1260, in add_q
web_1  |     clause, _ = self._add_q(q_object, self.used_aliases)
web_1  |   File "/usr/local/lib/python3.6/site-packages/django/db/models/sql/query.py", line 1286, in _add_q
web_1  |     allow_joins=allow_joins, split_subq=split_subq,
web_1  |   File "/usr/local/lib/python3.6/site-packages/django/db/models/sql/query.py", line 1216, in build_filter
web_1  |     condition = lookup_class(lhs, value)
web_1  |   File "/usr/local/lib/python3.6/site-packages/django/db/models/lookups.py", line 24, in __init__
web_1  |     self.rhs = self.get_prep_lookup()
web_1  |   File "/usr/local/lib/python3.6/site-packages/django/db/models/fields/related_lookups.py", line 110, in get_prep_lookup
web_1  |     self.rhs = target_field.get_prep_value(self.rhs)
web_1  |   File "/usr/local/lib/python3.6/site-packages/django/db/models/fields/__init__.py", line 962, in get_prep_value
web_1  |     return int(value)
web_1  | TypeError: int() argument must be a string, a bytes-like object or a number, not 'AnonymousUser'
1
which view are you hitting, which url? update your question with view code and url path. I'm feeling there is something wrong with your viewxxbinxx
Can you please post full error stack ?Umair Mohammad
I have already posted the full error stackAlexandros
Not really sure but maybe the problem is with this line: user_company = str(CustomUser.objects.get(user=request.user).seat.company.id)? Maybe the user kwarg you pass should be something else?Eyal C
that was the cause of the error, thank youAlexandros

1 Answers

1
votes

The error is being raised from within your permissions class.

When you check the CustomUser model with user_company = str(CustomUser.objects.get(user=request.user).seat.company.id), the request.user is an instance of AnonymousUser and not User, hence why it is failing. You should add some code to your permissions to check for an anonymous user with:

if request.user.is_anonymous:
    raise AuthenticationFailed() # You could also use PermissionDenied to return 403

# Unauthenticated users will receive an unauthorized (401) response

user_company = str(CustomUser.objects.get(user=request.user).seat.company.id)

is_anonymous is a property of the User and AnonymousUser classes intended to be used by developers to check if the user is actually authenticated or not.