Reputation: 159
I have this Django API view that I want to allow authorized and unauthorized users access it, I have set Django token-authentication as the default authentication class, however, whenever I try to access the view as unauthenticated user,I get error Unauthorized: which is weird coz am making a get request in the view my code is here
@api_view(['GET'])
@permission_classes([permissions.IsAuthenticatedOrReadOnly])
def all_Search(request):
print(request.headers)
src = request.GET.get('q')
my settings for rest framework is
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.TokenAuthentication',
'rest_framework.authentication.SessionAuthentication',
]
}
is there a way to work around this? will appreciate any help, thanks
Upvotes: 0
Views: 648
Reputation: 899
I've tried to reproduce your error but I failed. This is my configuration:
settings.py
INSTALLED_APPS = [
...
'rest_framework',
'rest_framework.authtoken'
]
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.TokenAuthentication',
'rest_framework.authentication.SessionAuthentication',
]
}
urls.py
urlpatterns = [
path('search/', api.all_search, name="search")
]
api.py
from rest_framework import permissions
from rest_framework.decorators import api_view, permission_classes
from rest_framework.response import Response
@api_view(['GET'])
@permission_classes([permissions.IsAuthenticatedOrReadOnly])
def all_Search(request):
print(request.headers)
src = request.GET.get('q')
return Response()
test.py
from rest_framework import status
from rest_framework.test import APILiveServerTestCase
from rest_framework.reverse import reverse
class TestTokenAuthorization(APILiveServerTestCase):
def test_can_search_without_token(self):
url = reverse('search', kwargs={})
response = self.client.get(url, {}, format='json')
self.assertEqual(response.status_code, status.HTTP_200_OK)
and this is the result of the test:
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
{'Cookie': '', 'Content-Type': 'application/octet-stream'}
Destroying test database for alias 'default'...
I'm using djangorestframework==3.10.3
and python3.7
As you can see, I didn't authenticate the request (no token is passed) and the headers were printed as expected from the permissions.
Maybe your issue is caused by something else in your code. Try to include more details in your question.
By the way, your all_Search
function is missing the return Response()
Upvotes: 1
Reputation: 159
Okey I just decided to try something and it seams to be working, at least for now. I somehow believed that DEFAULT_AUTHENTICATION_CLASSES was the issue in this case and in deed it was, so I had to just remove the
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.TokenAuthentication',
'rest_framework.authentication.SessionAuthentication',
]
}
#opt to use
#authentication_classes = [TokenAuthentication, SessionAuthentication]
#in my views that requires authentications
in my settings, this was not all though, but now I could access the view either authorized or not: (having auth token or not). but this was not getting authenticated user by default so I did this
make a view to get a user based on a given token
from django.contrib.auth.models import AnonymousUser
from rest_framework.authtoken.models import Token
def get_user(token):
try:
token = Token.objects.select_related('user').get(key=token)
return token.user
except:
return AnonymousUser
and get user in my view if token exists in the headers
@api_view(['GET'])
@permission_classes([permissions.IsAuthenticatedOrReadOnly])
def all_Search(request):
auth = request.headers.get('Authorization').split(' ')[1]
key = request.headers.get('Authorization').split(' ')[0]
if key == 'Token' and auth != 'null': #used null coz my frontend sends null if key is not available
user = get_user(auth)
print(user)
Upvotes: 0