how to change permissions for current view overriding the DEFAULT_PERMISSION_CLASSES in django rest-framework - python

how to change permissions for current view overriding the DEFAULT_PERMISSION_CLASSES in django rest-framework
Here is how i set my defaultpermissions in my settings.py :
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.TokenAuthentication', # <-- And here
],
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated',
]
}
and i need to use AllowAny on the signUp method :
#permission_classes([AllowAny,])
#api_view(["POST", ])
def add_new_user(request):
if request.method == "POST":
lang = request.data["lang"]
..........
.........
.......
Still, it returns Authentication credentials were not provided. .. I mainly need to have permissions with a token with every request but not the register and login request. how to do it ??

A Way to do that is using Object Level Permissions in Django.
You just setup as normally in settings.py and add manually a permission into every class view.
For me is the best way to do it. Normally will be Views witch is are Admin only, Authenticated or just Open.
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.TokenAuthentication',
],
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.DjangoObjectPermissions',#Object Level Permission
]
}
After set this line into your settings.py just follow adding a permission_classes into view. Like:
class LoginUser(APIView):
permission_classes = [AllowAny, ]
...
References
DjangoObjectPermissions
Django Class Based Views

Here is how I solved this :
in my settings.py i added both permissions classes
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.TokenAuthentication', # <-- And here
],
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated', #both are mentioned
'rest_framework.permissions.AllowAny',
]
}
and in my view, I had to move the permission dictator to be the last thing before the view itself.
#api_view(["POST", ])
#permission_classes([AllowAny])
def login_user(request):
if request.method == "POST":
lang = request.data["lang"]
...

Related

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

I have my token for admin, the booking entries is allowed in Insomnia but would not be allowed DRF display. I am missing something please? Is there way to provide the token for it to be allowed?
#view.py
from django.shortcuts import render, redirect
from django.contrib.auth.models import User
from rest_framework import viewsets
from .models import Booking, Menu
from .serializers import BookingSerializer, MenuSerializer, UserSerializer
from rest_framework.permissions import IsAuthenticated
from rest_framework.authentication import TokenAuthentication
from rest_framework import generics
from datetime import datetime
from django.views.decorators.csrf import csrf_exempt
from django.db.models import Sum
from django.contrib import messages
def home(request):
return render(request, 'index.html')
def about(request):
return render(request, 'about.html')
class UserRegistrationView(generics.CreateAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
class BookingViewSet(viewsets.ModelViewSet):
queryset = Booking.objects.all()
serializer_class = BookingSerializer
permission_classes = [IsAuthenticated]
authentication_classes = [TokenAuthentication]
settings.py
REST_FRAMEWORK = {
'DEFAULT_RENDERER_CLASSES': [
'rest_framework.renderers.JSONRenderer',
'rest_framework.renderers.BrowsableAPIRenderer',
],
'DEFAULT_AUTHENTICATION_CLASS': (
'rest_framework.authentication.TokenAuthentication',
'rest_framework.authentication.SessionAuthentication'
),
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated',
]
}
Select Headers Key will be Authorization and value will be like this
Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b
I think you need to remove session authentication class because here you used token for authentication
I mean authentication classes overrides.
So, remove session authentication class only put token authentication class
But, you want to authenticate with browsable you need to remove token authentication and need to put session authentication class.
If you want authenticate with with token you need to POSTMAN or other third -party API testing tool which support token authentication
and you need to remove session authentication and need to put token authentication class
settings for token authentication (test with Postman or other third -party API testing tool)
REST_FRAMEWORK = {
'DEFAULT_RENDERER_CLASSES': [
'rest_framework.renderers.JSONRenderer',
'rest_framework.renderers.BrowsableAPIRenderer',
],
'DEFAULT_AUTHENTICATION_CLASS': (
'rest_framework.authentication.TokenAuthentication',
),
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated',
]
}
settings for session authentication (test with browsable api which provides DRF built-in)
REST_FRAMEWORK = {
'DEFAULT_RENDERER_CLASSES': [
'rest_framework.renderers.JSONRenderer',
'rest_framework.renderers.BrowsableAPIRenderer',
],
'DEFAULT_AUTHENTICATION_CLASS': (
'rest_framework.authentication.SessionAuthentication',
),
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated',
]
}

Django permissions.IsAuthenticated can check on middleware

I want to create global authentication with middleware django restframework which check every request user authenticate or not.
I don't want to add code on every view class like this
#permission_classes([IsAuthenticated])
class UserProfile(APIView):
You just need to set the permissions policy for DRF in your settings.py file. Here the Docs
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated',
]
}

{ "detail": "Method \"GET\" not allowed." }

So the problem I have already mentioned. I am a beginner, I might be doing some silly mistakes. So humble request to you guys to address my mistake and help me to complete my project. Thanks you all in advance.
setting.py
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticatedOrReadOnly',
),
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.BasicAuthentication',
),
}
JWT_AUTH = {
'JWT_ALLOW_REFRESH': True,
'JWT_EXPIRATION_DELTA': datetime.timedelta(seconds=3600),
}
this is the setting.py file and here I mention the required file
view.py
class LoginViewSet(viewsets.ViewSet):
""" Check email and password and return auth token. """
serializer_class = AuthTokenSerializer
authentication_classes((SessionAuthentication, TokenAuthentication, BasicAuthentication))
permission_classes((IsAuthenticated,))
def create(self, request):
""" Use ObtainAuthToken APIView to validate and create a token. """
return ObtainAuthToken().post(request)
this is the view.py file.
urls.py
router.register('login', views.LoginViewSet, base_name="login")
urlpatterns = [
path('', include(router.urls)),
path('login/', ObtainAuthToken.as_view()),
path(r'api-token-auth/', obtain_jwt_token),
path(r'api-token-refresh/', refresh_jwt_token),
]
Error Message
error
you must define http_method_names in DRF and specify your method access in your api.
class IndexViewAPI(generics.GenericAPIView):
http_method_names = ['get', 'head']
# some statements

Getting Permissions issue on sending the authenticated request to OAuth2.0 Django rest Framwork

I Have integrated the OAuth2.0 with django-rest-framework. When I send the authenticated request to my class based view I got this
{
"detail": "You do not have permission to perform this action."
}
settings.py
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'oauth2_provider.contrib.rest_framework.OAuth2Authentication',
),
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
)
}
views.py
from rest_framework import permissions
from oauth2_provider.contrib.rest_framework import TokenHasReadWriteScope
class LogoutView(APIView):
"""
This will help in logout of user.
"""
authentication_classes = ()
permission_classes = (permissions.IsAuthenticated, TokenHasReadWriteScope)
def get(self, request):
return Response({'s': 'd'})
urls.py
from django.urls import path, re_path
from accounts.views import SignUpView, LoginView, LogoutView
urlpatterns = [
path('signup/', SignUpView.as_view()),
path('login/', LoginView.as_view()),
path('logout/', LogoutView.as_view()),
]
And this is what my headers look like
Content-Type:application/json
Authorization:Bearer 4A7qGgmHpbEWlJn5w4wCwxJ9jWfTZ5
This is the access token that I generated.
Make sure you have the following in your settings.py
AUTHENTICATION_BACKENDS = (
'oauth2_provider.backends.OAuth2Backend',
'django.contrib.auth.backends.ModelBackend'
)
And:
OAUTH2_PROVIDER = {
'REFRESH_TOKEN_EXPIRE_SECONDS': 360000,
'SCOPES': {'read': 'Read scope', 'write': 'Write scope', 'groups': 'Access to your groups'},
'ACCESS_TOKEN_EXPIRE_SECONDS': 1800
}
For debugging purposes:
Remove authentication_classes = () from view.py
Remove TokenHasReadWriteScope from view.py
If you want to make a logout endpoint, I would recommend using oauth2_views in your urls.py:
from oauth2_provider import views as oauth2_views
#.....
urlpatterns = [
#....
url(r'^logout/$', oauth2_views.RevokeTokenView.as_view()),
]

Django rest framework not authenticating custom user model

I have this custom user model:
class CustomUser(AbstractBaseUser,PermissionsMixin):
email = models.CharField(max_length=255, unique=True)
....
And this view that is supossed to require authentication in order to run:
#authentication_classes((TokenAuthentication,))
#permission_classes((IsAuthenticated,))
def test_view(request):
return HttpResponse("Allowed")
When i launch the url for this, it will always run no matter if i provide credentials or not in my authorization header. My guess is that rest framework is using django's default user model, since the request.user object contains an AnonymousUser instance. But i have checked the database, and the authtoken table is referencing my custom user table.
I thoguht that this should be as simple as my code is, but i guess im missing something. Any ideas?
Edit: here are more details:
settings.py:
INSTALLED_APPS = (
'myapps',
...
'django.contrib.auth', #should this be enabled?
...
'rest_framework.authtoken'
)
...
#I think this is unnecesary since i use per-view decorators, but...
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
)
}
AUTH_USER_MODEL = 'users.CustomUser'
urls.py:
urlpatterns = patterns('',
...
url(r'^test', test_view, name='test'),
...
)
just add #api_view(['GET']) decorator to your view like
from rest_framework.decorators import api_view
#api_view(['GET'])
#authentication_classes((TokenAuthentication,))
#permission_classes((IsAuthenticated,))
def test_view(request):
return HttpResponse("Allowed")
Add the following to settings.py
If you're using DRF token Auth:
INSTALLED_APPS = (
...
'rest_framework.authtoken'
)
If you're using JWT Auth:
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
),
...
}

Categories

Resources