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

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

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 rest framework jwt {"detail": "You do not have permission to perform this action."}

I am trying to make a request using django-rest-framework and django-rest-framework-jwt but The response that I get detail": "You do not have permission to perform this action."
views.py
class Test(generics.RetrieveAPIView):
permission_classes = [IsAuthenticated]
authentication_classes = []
queryset = User.objects.all()
def get(self, request):
return response.Response({"test": "Test "}, status=status.HTTP_200_OK)
urls.py
from rest_framework_jwt.views import obtain_jwt_token, refresh_jwt_token
from .views import Test
urlpatterns = [
path('', Test.as_view(), name='test'),
path('token/', obtain_jwt_token, name='token_obtain_pair'),
path('token/refresh/', refresh_jwt_token, name='token_refresh'),
]
settings.py
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
),
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.BasicAuthentication',
),
}
JWT_AUTH = {
'JWT_ENCODE_HANDLER':
'rest_framework_jwt.utils.jwt_encode_handler',
'JWT_DECODE_HANDLER':
'rest_framework_jwt.utils.jwt_decode_handler',
'JWT_PAYLOAD_HANDLER':
'rest_framework_jwt.utils.jwt_payload_handler',
'JWT_PAYLOAD_GET_USER_ID_HANDLER':
'rest_framework_jwt.utils.jwt_get_user_id_from_payload_handler',
'JWT_RESPONSE_PAYLOAD_HANDLER':
'rest_framework_jwt.utils.jwt_response_payload_handler',
'JWT_SECRET_KEY': SECRET_KEY,
'JWT_GET_USER_SECRET_KEY': None,
'JWT_PUBLIC_KEY': None,
'JWT_PRIVATE_KEY': None,
'JWT_ALGORITHM': 'HS256',
'JWT_VERIFY': True,
'JWT_VERIFY_EXPIRATION': True,
'JWT_LEEWAY': 0,
'JWT_EXPIRATION_DELTA': timedelta(days=5),
'JWT_AUDIENCE': None,
'JWT_ISSUER': None,
'JWT_ALLOW_REFRESH': True,
'JWT_REFRESH_EXPIRATION_DELTA': timedelta(days=7),
'JWT_AUTH_HEADER_PREFIX': 'JWT',
'JWT_AUTH_COOKIE': None,
}
and the request that I made:
>curl -X GET http://127.0.0.1:8000/users/ -H 'Authorization: Token eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxMCwidXNlcm5hbWUiOiJoYXNhbm1iaWxhbDE5OThAZ21haWwuY29tIiwiZXhwIjoxNjUxNTkxMDYxLCJlbWFpbCI6Imhhc2FubWJpbGFsMTk5OEBnbWFpbC5jb20iLCJvcmlnX2lhdCI6MTY1MTE1OTA2MX0.bvmtH6mnItBjwKkvaNU5eMXlEyk2ZAytMWzhEE_Ibhs'
Note: I've used django-rest-framework-simplejwt and got the same problem...
You've set your authentication_classes=[], so auth is not run for this view
You then require they are logged in with your permissions_classes
For now just remove the authentication_classes = [] from the view. Your default permissions also require authentication, so that line could also be removed.
Based on your usage here you should probably use APIView rather than the generics. If you plan to use the features of the generics (and construct the routes correctly manually) then keep at it.
class Test(APIView):
# use default permission_classes in REST_FRAMEWORK
# use default authentication_classes in REST_FRAMEWORK
def get(self, request):
return Response({"data": "Test"})
To answer your new question, and after referring to the documentation for the rest_framework_jwt package, you need to send the token as Authorization: JWT {token}.
If this isn't the right documentation or package, please send a link to the correct one along with the location that says to use Token (which is actually how simple_jwt works, not this package).
In your settings file you actually override all the default settings, when you only need the ones you want to change. In this list, at the bottom, I see this:
'JWT_AUTH_HEADER_PREFIX': 'JWT',

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

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"]
...

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