machineghost
machineghost

Reputation: 35725

How Can I Disable Authentication in Django REST Framework

I'm working on a store site, where every user is going to be anonymous (well, until it's time to pay at least), and I'm trying to use Django REST Framework to serve the product API, but it keeps complaining about:

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

I found some settings related to authentication, but I couldn't find anything like ENABLE_AUTHENTICATION = True. How do I simply disable authentication, and let any visitor to the site access the API?

Upvotes: 98

Views: 90415

Answers (10)

user22787100
user22787100

Reputation: 1

#in settings.py

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



class ListView(APIView):
    authentication_classes = [TokenAuthentication]
    permission_classes = [IsAuthenticated]
    def get(self,request):
        customers = Customer.objects.filter(is_superuser=False)
        serializer = CustomerSerializer(customers, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)

Upvotes: 0

Roman Rekrut
Roman Rekrut

Reputation: 53

Also, it can be the separate class for the dev.

class DevAuthentication(authentication.BaseAuthentication):
    def authenticate(self, request):
        return models.User.objects.first(), None

And in settings.py:

DEFAULT_AUTHENTICATION_CLASSES = ["common.authentication.DevAuthentication"]

Upvotes: 1

Aashish Soni
Aashish Soni

Reputation: 939

You can also disable authentication for particular class or method, just keep blank the decorators for the particular method.

from rest_framework.decorators import authentication_classes, permission_classes

@authentication_classes([])
@permission_classes([])
@api_view(['POST']) 
def items(request):
   return Response({"message":"Hello world!"})
   

Upvotes: 83

mPrinC
mPrinC

Reputation: 9411

For class view you can do:

from rest_framework.permissions import AllowAny
from rest_framework.response import Response
from rest_framework.views import APIView

class ExampleView(APIView):
    permission_classes = [AllowAny]

    def get(self, request, format=None):
        content = {
            'status': 'request was permitted'
        }
        return Response(content)

For function view you can do:


from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import AllowAny
from rest_framework.response import Response

@api_view(['GET'])
@permission_classes([AllowAny])
def example_view(request, format=None):
    content = {
        'status': 'request was permitted'
    }
    return Response(content)

More details at Setting the permission policy

Upvotes: 4

Sumithran
Sumithran

Reputation: 6565

if you want to disable authentication for a certain class based view, then you can use,

class PublicEndPoint(APIView):
    authentication_classes = [] #disables authentication
    permission_classes = [] #disables permission
    
    def get(self, request):
        pass

This is useful when you want to make only specific endpoints available public.

Upvotes: 35

rbento
rbento

Reputation: 11678

Here is an alternative to simply enable the API forms for development purposes:

settings.py

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.AllowAny'
    ]
}

Django REST framework v3.11.0

Upvotes: 4

Riley Davidson
Riley Davidson

Reputation: 377

To enable authentication globally add this to your django settings file:

'DEFAULT_AUTHENTICATION_CLASSES': (
    'rest_framework.authentication.TokenAuthentication',
),
'DEFAULT_PERMISSION_CLASSES': (
    'rest_framework.permissions.IsAuthenticated',
),

then add the following decorators to your methods to enable unauthenticated access to it

from rest_framework.decorators import authentication_classes, permission_classes

@api_view(['POST'])
@authentication_classes([])
@permission_classes([])
def register(request):
  try:
    username = request.data['username']
    email = request.data['email']
    password = request.data['password']
    User.objects.create_user(username=username, email=email, password=password)
    return Response({ 'result': 'ok' })
  except Exception as e:
    raise APIException(e)

Upvotes: 10

Umar Asghar
Umar Asghar

Reputation: 4064

You can also apply it on one specific endpoint by applying it on class or method. Just need to apply django rest framework AllowAny permission to the specific method or class.

views.py

from rest_framework.permissions import AllowAny

from .serializers import CategorySerializer
from catalogue.models import Category   

@permission_classes((AllowAny, ))
class CategoryList(generics.ListAPIView):
    serializer_class = serializers.CategorySerializer
    queryset = Category.objects.all()

You can achieve the same result by using an empty list or tuple for the permissions setting, but you may find it useful to specify this class because it makes the intention explicit.

Upvotes: 11

Slipstream
Slipstream

Reputation: 14802

If using APIView you can create a permission for the view, example below:

urls.py

url(r'^my-endpoint', views.MyEndpoint.as_view())

permissions.py

class PublicEndpoint(permissions.BasePermission):
    def has_permission(self, request, view):
        return True

views.py

from permissions import PublicEndpoint

class MyEndpoint(APIView):

    permission_classes = (PublicEndpoint,)

    def get(self, request, format=None):
        return Response({'Info':'Public Endpoint'})

Upvotes: 7

inancsevinc
inancsevinc

Reputation: 2708

You can give empty defaults for the permission and authentication classes in your settings.

REST_FRAMEWORK = {
    # other settings...

    'DEFAULT_AUTHENTICATION_CLASSES': [],
    'DEFAULT_PERMISSION_CLASSES': [],
}

Upvotes: 91

Related Questions