Django Rest Framework - Authentication credentials were not provided

PythonDjangoDjango Rest-Framework

Python Problem Overview


I'm developing an API using Django Rest Framework. I'm trying to list or create an "Order" object, but when i'm trying to access the console gives me this error:

{"detail": "Authentication credentials were not provided."}

Views:

from django.shortcuts import render
from rest_framework import viewsets
from django.contrib.auth.models import User
from rest_framework.renderers import JSONRenderer, YAMLRenderer
from rest_framework.response import Response
from rest_framework.views import APIView
from order.models import *
from API.serializers import *
from rest_framework.permissions import IsAuthenticated

class OrderViewSet(viewsets.ModelViewSet):
	model = Order
	serializer_class = OrderSerializer
	permission_classes = (IsAuthenticated,)

Serializer:

class OrderSerializer(serializers.HyperlinkedModelSerializer):

	class Meta:
		model = Order
		fields = ('field1', 'field2')

And my URLs:

# -*- coding: utf-8 -*-
from django.conf.urls import patterns, include, url
from django.conf import settings
from django.contrib import admin
from django.utils.functional import curry
from django.views.defaults import *
from rest_framework import routers
from API.views import *

admin.autodiscover()

handler500 = "web.views.server_error"
handler404 = "web.views.page_not_found_error"

router = routers.DefaultRouter()
router.register(r'orders', OrdersViewSet)

urlpatterns = patterns('',
    url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
    url(r'^api-token-auth/', 'rest_framework.authtoken.views.obtain_auth_token'),
    url(r'^api/', include(router.urls)),
)

And then I'm using this command in the console:

curl -X GET http://127.0.0.1:8000/api/orders/ -H 'Authorization: Token 12383dcb52d627eabd39e7e88501e96a2sadc55'

And the error say:

{"detail": "Authentication credentials were not provided."}

Python Solutions


Solution 1 - Python

If you are running Django on Apache using mod_wsgi you have to add

WSGIPassAuthorization On

in your httpd.conf. Otherwise, the authorization header will be stripped out by mod_wsgi.

Solution 2 - Python

Solved by adding "DEFAULT_AUTHENTICATION_CLASSES" to my settings.py

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

Solution 3 - Python

This help me out without "DEFAULT_PERMISSION_CLASSES" in my settings.py

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.TokenAuthentication',
        'rest_framework.authentication.SessionAuthentication',
    ),
    'PAGE_SIZE': 10
}

Solution 4 - Python

Just for other people landing up here with same error, this issue can arise if your request.user is AnonymousUser and not the right user who is actually authorized to access the URL. You can see that by printing value of request.user . If it is indeed an anonymous user, these steps might help:

  1. Make sure you have 'rest_framework.authtoken' in INSTALLED_APPS in your settings.py.

  2. Make sure you have this somewhere in settings.py:

     REST_FRAMEWORK = {
     
         'DEFAULT_AUTHENTICATION_CLASSES': (
             'rest_framework.authentication.TokenAuthentication',
             # ...
         ),
         
         # ...
     }
    
  3. Make sure you have the correct token for the user who is logged in. If you do not have the token, learn how to get it here. Basically, you need to do a POST request to a view which gives you the token if you provide the correct username and password. Example:

     curl -X POST -d "user=Pepe&password=aaaa"  http://localhost:8000/
    
  4. Make sure the view which you are trying to access, has these:

     class some_fancy_example_view(ModelViewSet): 
     """
     not compulsary it has to be 'ModelViewSet' this can be anything like APIview etc, depending on your requirements.
     """
         permission_classes = (IsAuthenticated,) 
         authentication_classes = (TokenAuthentication,) 
         # ...
    
  5. Use curl now this way:

     curl -X (your_request_method) -H  "Authorization: Token <your_token>" <your_url>
    

Example:

    curl -X GET http://127.0.0.1:8001/expenses/  -H "Authorization: Token 9463b437afdd3f34b8ec66acda4b192a815a15a8"

Solution 5 - Python

If you are playing around in the command line (using curl, or HTTPie etc) you can use BasicAuthentication to test/user your API

    REST_FRAMEWORK = {
        'DEFAULT_PERMISSION_CLASSES': [
            'rest_framework.permissions.IsAuthenticated',
        ],
        'DEFAULT_AUTHENTICATION_CLASSES': (
            'rest_framework.authentication.BasicAuthentication',  # enables simple command line authentication
            'rest_framework.authentication.SessionAuthentication',
            'rest_framework.authentication.TokenAuthentication',
        )
    }

You can then use curl

curl --user user:password -X POST http://example.com/path/ --data "some_field=some data"

or httpie (its easier on the eyes):

http -a user:password POST http://example.com/path/ some_field="some data"

or something else like Advanced Rest Client (ARC)

Solution 6 - Python

I too faced the same since I missed adding

> authentication_classes = (TokenAuthentication)

in my API view class.

class ServiceList(generics.ListCreateAPIView):
    authentication_classes = (SessionAuthentication, BasicAuthentication, TokenAuthentication)
    queryset = Service.objects.all()
    serializer_class = ServiceSerializer
    permission_classes = (IsAdminOrReadOnly,)

In addition to the above, we need to explicitly tell Django about the Authentication in settings.py file.

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

Solution 7 - Python

For me, I had to prepend my Authorization header with "JWT" instead of "Bearer" or "Token" on Django DRF. Then it started working. eg -

Authorization: JWT asdflkj2ewmnsasdfmnwelfkjsdfghdfghdv.wlsfdkwefojdfgh

Solution 8 - Python

I was having this problem with postman.Add this to the headers... enter image description here

Solution 9 - Python

Adding SessionAuthentication in settings.py will do the job

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': ( 
        'rest_framework.authentication.SessionAuthentication',
    ),
}

Solution 10 - Python

Try this, it worked for me.

In settings.py

SIMPLE_JWT = {
     ....
     ...
     # Use JWT 
     'AUTH_HEADER_TYPES': ('JWT',),
     # 'AUTH_HEADER_TYPES': ('Bearer',),
     ....
     ...
}

Add this too

REST_FRAMEWORK = {
    ....
    ...
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_simplejwt.authentication.JWTAuthentication',
    )
    ...
    ..
}

Solution 11 - Python

Since it is session Login so you need to provide you credentials so do 127.0.0:8000/admin admin and login later it will work fine

Solution 12 - Python

If you are using authentication_classes then you should have is_active as True in User model, which might be False by default.

Solution 13 - Python

if anyone come here from Full Stack React & Django [5] - Django Token Authentication - Traversy Media So you need to something like this

accounts/api.py

from rest_framework import generics, permissions
from rest_framework.response import Response
from knox.models import AuthToken
from .serializers import LoginSerializer, RegisterSerializer, UserSerializer
from knox.auth import TokenAuthentication

# Register Api


class RegisterAPI(generics.GenericAPIView):
    serializer_class = RegisterSerializer

    def post(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        user = serializer.save()
        return Response({
            "user": UserSerializer(user, context=self.get_serializer_context()).data,
            "token": AuthToken.objects.create(user)[1]
        })

# Login Api


class LoginAPI(generics.GenericAPIView):
    serializer_class = LoginSerializer

    def post(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        user = serializer.validated_data
        return Response({
            "user": UserSerializer(user, context=self.get_serializer_context()).data,
            "token": AuthToken.objects.create(user)[1]
        })

# Get User Api


class UserAPI(generics.RetrieveAPIView):
    authentication_classes = (TokenAuthentication,)
    permission_classes = [
        permissions.IsAuthenticated,
    ]

    serializer_class = UserSerializer

    def get_object(self):
        return self.request.user

Solution 14 - Python

Also make sure that the Authorization Token / API key is actually valid. The Authentication credentials were not provided. error message seems to be what's returned by the API if the key is invalid as well (I encountered this when I accidently used the wrong API key).

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMarcos AguayoView Question on Stackoverflow
Solution 1 - PythonRobert KovacView Answer on Stackoverflow
Solution 2 - PythonMarcos AguayoView Answer on Stackoverflow
Solution 3 - PythonuestcfeiView Answer on Stackoverflow
Solution 4 - PythonsherelockView Answer on Stackoverflow
Solution 5 - PythonlukeausView Answer on Stackoverflow
Solution 6 - PythonprashantView Answer on Stackoverflow
Solution 7 - Pythonkiko carisseView Answer on Stackoverflow
Solution 8 - PythonmikelusView Answer on Stackoverflow
Solution 9 - PythonPritam RoyView Answer on Stackoverflow
Solution 10 - PythonHarshit GangwarView Answer on Stackoverflow
Solution 11 - PythonAishwarya kabadiView Answer on Stackoverflow
Solution 12 - PythonPiyush JaiswalView Answer on Stackoverflow
Solution 13 - PythonAkash ShendageView Answer on Stackoverflow
Solution 14 - PythonrecvfromView Answer on Stackoverflow