I would like to limit the access to myweb/api in django rest framework.
I've tried:
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
)
}
But it limits all the requests however I want to limit access only to myweb/api page
You could add liberal permissions in settings.py file and add more restrictive ones in the specific api view.
In settings.py, add something like :
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly'
),
of you could also use AllowAny permission.
You can set the authentication policy on a per-view, or per-viewset basis, using the APIView class based views.
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView
class ExampleView(APIView):
permission_classes = (IsAuthenticated,)
def get(self, request, format=None):
content = {
'status': 'request was permitted'
}
return Response(content)
Or, if you're using the #api_view decorator with function based views.
from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
#api_view('GET')
#permission_classes((IsAuthenticated, ))
def example_view(request, format=None):
content = {
'status': 'request was permitted'
}
return Response(content)
When you set new permission classes through class attribute or decorators you're telling the view to ignore the default list set over the settings.py file.
Related
I have a class someAPI(APIView). I would like this one to be accessed by only authorised users.
I tried this link How to use login_required in django rest view
and
https://www.django-rest-framework.org/api-guide/authentication/
but none of them seem work.
My current authentication protocol is logging in with username and password. I guess a reason is because I implement this authentication with basic django (https://docs.djangoproject.com/en/3.1/topics/auth/default/) but not DRF.
from rest_framework.views import APIView
from rest_framework import authentication, permissions
from django.http import JsonResponse
class APICostAnalysisController(APIView):
permission_classes = [permissions.IsAuthenticated]
def get(self, request):
""" Initiate get API for getting cost analysis """
return JsonResponse(APICostAnalysisImpl().get(), safe=False,json_dumps_params={'indent': 2})
I have the following in my views.py
I've been reading the documentation and trying to work out is there a way to exclude certain endpoints for this view.
from EoX.models import Vendor
from rest_framework import viewsets
from rest_framework import permissions
from .serializers import VendorSerializer
from url_filter.integrations.drf import DjangoFilterBackend
from drf_yasg.utils import swagger_auto_schema
from django.utils.decorators import method_decorator
class VendorViewSet(viewsets.ModelViewSet):
queryset = Vendor.objects.all()
serializer_class = VendorSerializer
permission_classes = [permissions.AllowAny]
filter_backends = [DjangoFilterBackend]
filter_fields = ['name',]
I can exclude the view all together with
schema=None
I tried decorating it with
#method_decorator(name='list', decorator=swagger_auto_schema(
operation_description="description from swagger_auto_schema via method_decorator"
))
and that changes the description of the 'get' endpoint.
but trying
#method_decorator(name='list', decorator=swagger_auto_schema(methods=['get'],
operation_description="description from swagger_auto_schema via method_decorator"
))
throws an error
AssertionError:methodormethodscan only be specified on #action or #api_view views
Is this a bug? or just not a supported feature, and is there a way to accomplish what I am trying?
Many thanks.
I'd like to set permission per view or method using Django rest-framework Social Oauth2.
How should I set permission to each view or method?
At first, I've tried to set 'DEFAULT_AUTHENTICATION_CLASSES' in settings.py. But some method doesn't need authentication, I'd like to set AllowAny. So, I've tried to set decorator to the method but it doesn't work.
settings.py
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'oauth2_provider.contrib.rest_framework.OAuth2Authentication',
'rest_framework_social_oauth2.authentication.SocialAuthentication',
),
}
views.py
#permission_classes([AllowAny, ])
#api_view(['POST'])
def someMethod(request):
return foo
I resolved it by myself. Commented out DEFAULT_AUTHENTICATION_CLASSES on settings.py. And imported these Authentification and authentication_classes on views.py.
settings.py
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
# 'oauth2_provider.contrib.rest_framework.OAuth2Authentication',
# 'rest_framework_social_oauth2.authentication.SocialAuthentication',
),
}
views.py
from rest_framework.decorators import authentication_classes
from oauth2_provider.contrib.rest_framework import OAuth2Authentication
from rest_framework_social_oauth2.authentication import SocialAuthentication
class SampleViewSet(viewsets.ViewSet):
authentication_classes = [OAuth2Authentication, SocialAuthentication]
def someMethodNeedAuth:
return foo
#authentication_classes([AllowAny, ])
#api_view(['POST'])
def someMethodAllowAny(request):
return bar
I'm trying to set custom permissions on a class that extends viewsets.ModelViewSet and it appears that my permissions are not being evaluated. Here is my view:
from rest_framework import viewsets
from rest_framework.authentication import SessionAuthentication, BasicAuthentication
from rest_framework.permissions import IsAuthenticated
import models
import serializers
from permissions import IsAdminOrAuthenticatedReadOnly
class KPIViewSet(viewsets.ModelViewSet):
'''
API endpoint that allows KPI metadata to be viewed or edited
'''
authentication_classes = (BasicAuthentication,)
permission_classes = (IsAdminOrAuthenticatedReadOnly,)
queryset = models.KPI.objects.all()
serializer_class = serializers.KPISerializer
And here is my permission class:
from rest_framework.permissions import BasePermission, SAFE_METHODS
class IsAdminOrAuthenticatedReadOnly(BasePermission):
def has_permissions(self, request, view):
if request.method in SAFE_METHODS:
return request.user and request.user.is_authenticated()
return request.user and request.user.is_staff()
The problem I'm running into is that IsAdminOrAuthenticatedReadOnly never seems to get evaluated. I tested this both by forcing it to always return "False" and by switching the permission_classes value to "IsAuthenticated" in the view. In the former scenario, a request to the endpoint returns as if there were no authentication requirement. In the later, authentication is enforced as expected.
Any ideas what I'm missing?
The method name is has_permission not has_permissions (no s) ;)
I am trying to make MongoEngine work with Django REST framework. By following this link Getting mongoengine and django rest framework to play nice, I manage to get everything working, but have to disable "PERMISSION CLASSES" in REST framework, like below
'DEFAULT_PERMISSION_CLASSES': [
#'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly'
]
Otherwise, I get this error "Cannot apply DjangoModelPermissions on a view that does not have .model or .queryset property.". The reason seems to be that the returned value from "Collection.objects" or "Collection.objects.all()" can not pass "has_permission" function in permission.py in REST framework.
Could anyone help to look at this?
Or you can just add:
from rest_framework import permissions
and in the view classes add
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
In your views.py import the following models:
from rest_framework.permissions import AllowAny
from rest_framework.decorators import api_view, permission_classes
Before declaring the function (the view function) add:
#api_view(['GET', 'POST'])
#permission_classes((AllowAny, ))
or
#api_view(['GET', 'PUT', 'DELETE'])
#permission_classes((AllowAny, ))
As per Django REST docs:
This permission class ties into Django's standard django.contrib.auth
model permissions. This permission must only be applied to views
that have a .queryset property or get_queryset() method.
This means that on your view, you must have the queryset properly set, e.g:
queryset = SampleModel.objects.all()
Best approach will be to authenticate at a view-base level. So your view must look like this:
from rest_framework.views import APIView
from rest_framework.permissions import DjangoModelPermissionsOrAnonReadOnly
class SampleAPIView(APIView):
queryset = SampleModel.objects.all()
serializer_class = SampleSerializer
permission_classes = [DjangoModelPermissionsOrAnonReadOnly,]
And just in case you are using JWT authentication, you just need to add this to settings.py:
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_simplejwt.authentication.JWTAuthentication',
)
}