I used Django REST Swagger in my Django project. It is able to show all the URL with views which does not have
permission_classes = [IsAuthenticated]. While the view with permission_classes = [IsAuthenticated] is not shown in the list-api.
Here is an example:
class EquipmentCategoryViewSet(ResponseMixin, viewsets.ModelViewSet):
queryset = EquipmentCategory.objects.all()
serializer_class = EquipmentCategorySerializer
permission_classes = [IsAuthenticated]
if i remove permission_classes = [IsAuthenticated], it is shown in the swagger list-api.
I downgraded swagger to 2.1.2 and clicked on authorized and passed the token.
The strange thing is I have a prefix 'Token' in my value. When i login with Token<tokenvalue> login fails. But when I pass <tokenvalue> it gets authenticated but the views with isAuthenticated is not shown.
Please suggest what should be done to show views with isAuthenticated added.
In document API top right corner there is a option for authorise or to log in. Do provide valid token in it or login. This will list other endpoints.
Use swagger 2.1.2.
The latest django swagger version 2.2 has some issue with
authorization. Refer:
https://github.com/marcgibbons/django-rest-swagger/issues/762
you can just override the schema
from rest_framework.schemas import get_schema_view
from rest_framework_swagger import renderers
schema_view = get_schema_view(title="Fbs Api Docs", public=True, renderer_classes=[renderers.OpenAPIRenderer, renderers.SwaggerUIRenderer])
you pass the public=True it will allow all api to list, in
urls.py include below
path('docs/', schema_view),
Related
I want to create a POST request from React to DRF for a normal search functionality: ANYONE on the site can input something in a search field and that data will be used to query the database. I do not need the users to be authenticated or anything. In DRF there needs to be an authentication class and I dont know which one to use. Any ideas?
Set permission_classes and authentication_classes to empty
from rest_framework.views import APIView
class MyPublicView(APIView):
permission_classes = []
authentication_classes = []
You can use any DRF view instead of APIView. This procedure is same for all CBVs in DRF.
With Django REST Framework(DRF) I can customize Authentication class and Permission class simply like this
from django_cognito_jwt import JSONWebTokenAuthentication
from rest_framework import viewsets
from rest_framework.permissions import IsAuthenticated
class CognitoQuestionViewSet(viewsets.ModelViewSet):
authentication_classes = (JSONWebTokenAuthentication,)
permission_classes = (IsAuthenticated,)
queryset = Question.objects.all()
serializer_class = QuestionSerializer
In the GraphQL docs. It is using standard Django login which is different from my project. I had checked with source LoginRequiredMixin but no luck. I don't see Authentication class there then I can override it
Problem:
How to customize GraphQL Authentication class and Permission class like one I did in DRF
After trials and tries with django-graphql-jwt with no luck. vinayan3 has the answer on my question. Because django-cognito-jwt is considered as a DRF complement.
Solution:
Just replace TokenAuthentication with JSONWebTokenAuthentication from django_cognito_jwt
I am newbie to Django Rest Framework. I googled a lot and stuck on How to set User Role to User and strict to Permission.
My question is very basic but I don't know how to do it.
I want to create 2 types of Users:
1) Admin (Full Access)
2) Normal User (Limited Access)
I found some links but still on getting what to do:
Django rest-framework per action permission
django-rest-framework : setting per user permissions
you can separate users by is_staff property and use, standart rest permission isadminuser, for test you try this simple view
from rest_framework.permissions import IsAdminUser
from rest_framework.response import Response
from rest_framework.views import APIView
class ExampleView(APIView):
permission_classes = (IsAdminUser,)
def get(self, request, format=None):
content = {
'status': 'request was permitted'
}
return Response(content)
I have a Django web application which requires authentication across the whole site. I've accomplished that with custom middleware which basically test if request.user.is_anonymous and, if they are, redirects them to the login page. It looks like this:
from django.contrib.auth.views import login
from django.contrib.auth import authenticate
from django.http import HttpResponseRedirect, HttpResponse
from django.utils import simplejson
from django.core import serializers
class SiteLogin:
"This middleware requires a login for every view"
def process_request(self, request):
if request.path != '/accounts/login/' and request.user.is_anonymous():
if request.POST:
return login(request)
else:
return HttpResponseRedirect('/accounts/login/?next=%s' % request.path)
Now I'm making an iOS app which, for now, will just do GET requests off the Django server. I am trying to use TastyPie to do this but I can't get the the authentication working. I am using ApiKeyAuthentication and, I believe, have set it up properly. However, it just redirects me to the login page. I'm wondering if I need to edit this middleware to handle TastyPie requests, but I thought TastyPie could to auth for me...
I feel like my situation is very similar to this question, but I wonder if my custom middleware is getting in the way.
Here's my api.py:
from django.contrib.auth.models import User
from django.db import models
from tastypie.resources import ModelResource
from cpm.systems.models import System
from cpm.products.models import Product
from tastypie.models import create_api_key
from tastypie.authentication import ApiKeyAuthentication
from tastypie.authorization import DjangoAuthorization, Authorization
models.signals.post_save.connect(create_api_key, sender=User)
class SystemResource(ModelResource):
class Meta:
queryset = System.objects.all()
resource_name = 'system'
authentication = ApiKeyAuthentication()
authorization = DjangoAuthorization()
class ProductResource(ModelResource):
class Meta:
queryset = Product.objects.all()
resource_name = 'product'
authentication = ApiKeyAuthentication()
authorization = DjangoAuthorization()
And a portion of my urls.py:
from cpm.ios.api import SystemResource, ProductResource
from tastypie.api import Api
v1_api = Api(api_name='v1')
v1_api.register(SystemResource())
v1_api.register(ProductResource())
admin.autodiscover()
urlpatterns = patterns('',
# iOS TastyPie related:
(r'^ios/', include(v1_api.urls)),
# .... more urls....
The URL I try to navigate to is:
http://192.168.1.130:8080/ios/v1/system/C0156/?username=garfonzo&api_key=12345?format=json
But I'm just redirected to my login page. I've followed the tutorial to a tee, created an api key on my Admin panel, and added WSGIPassAuthorization On to my apache config.
Any ideas?
EDIT I just removed that middleware altogether and now all I receive are 401 AUTHENTICATION errors...
EDIT 2
I should point out that if I remove the ?format=json then I get a response of: Sorry, not implemented yet. Please append "?format=json" to your URL.. So it's like it does authenticate, but then fails because I'm not specifying the format.
So my URL looks like this: http://192.168.1.130:8080/ios/v1/system/C0156/?username=garfonzo&api_key=12345 but as soon as I add the ?format=JSON then it goes to a 401 error.
TastyPie requests go through the same stack of middlewares as any typical django request. So, it's definitely your middleware. You have to rethink it, or just drop to the basics and use #login_required.
The api key doesn't work after you disabled the middleware because your URL is malformed. You can't use a ? in a querystring after you used it once. Try this url:
http://192.168.1.130:8080/ios/v1/system/C0156/?username=garfonzo&api_key=12345&format=JSON
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',
)
}