Can't authenticate a user in Django rest framework - django

I'm trying to get data of an authenticated user using the token,
I'm using postman to send a get request and get the data I need but I'm receiving a response
"detail": "Authentication credentials were not provided."
this is the view
`
class ReceiveMessagesView(viewsets.ModelViewSet):
serializer_class = MessageSerializer
permission_classes = [permissions.IsAuthenticated]
http_method_names = ['get', 'post']
def get_queryset(self):
user = self.request.user
queryset = Message.objects.filter(receiver=user)
return queryset`
settings
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
'rest_framework.authentication.SessionAuthentication',
),
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
),
}
urls
router = routers.DefaultRouter()
router.register('', views.ReceiveMessagesView, basename='receive_messages')
urlpatterns = [
path('', include(router.urls))
]
serializer
class MessageSerializer(serializers.ModelSerializer):
class Meta:
model = Message
fields = [
'sender',
'receiver',
'subject', 'msg',
'creation_date',
]
In the postman request I'm sending in Authorization the key as "Token" and the value as the user I want data about's token
I am trying to send an authorized get request and received an authorized user's data
btw if I'm trying to print the user instance and the token when I get to the view (with self.request.user and self.request.auth)I get the correct instance user but for the token I get None

Set a key:value at the HEADER of the HTTP request. You just need a valid token:
KEY: Authorization
VALUE: Token yourtokenvalue

If you try to Authenticate with Token authentication using POSTMAN, you need to pass only 'rest_framework.authentication.TokenAuthentication', in DEFAULT_AUTHENTICATION_CLASSES
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
),
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
),
}

Related

Block users from viewing page

so I'm getting this weird issue. I have my simpleJWT auth working on the server but for some reason, I can't get
permission_classes=[permissions.IsAuthenticated]
to block the view from an anonymous user.
There are many similar posts but I can't figure out where the issue is.
from rest_framework import permissions
class UsersListView(ListView):
http_method_names = ['get']
permission_classes=[permissions.IsAuthenticated]
def get_queryset(self):
return UserModel.objects.all().exclude(id=self.request.user.id)
def render_to_response(self, context, **response_kwargs):
users: List[AbstractBaseUser] = context['object_list']
data = [{
"username": user.user_name,
"pk": str(user.pk)
} for user in users]
return JsonResponse(data, safe=False, **response_kwargs)
I've tried the dumbest approach first and removed allow any from here but no luck
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.AllowAny',
],
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_simplejwt.authentication.JWTAuthentication',
)
}
Can you spot the issue?

Getting "Authentication credentials were not provided" error when I don't want to require authentication

I have a project with JWT authentication in Django Rest Framework. Usually I require user to be authenticated but in the case of GET action (both list and retrieve) I would like everyone to be able to access it with no authentication required.
The code for this functionality is very simple:
class GetUserViewSet(viewsets.GenericViewSet,
mixins.ListModelMixin,
mixins.RetrieveModelMixin):
# allowed for everyone
serializer_class = UserSerializer
permission_classes = [permissions.AllowAny]
queryset = User.objects.all()
The permissions are set to allow any but there is probably some inconsistency with default auth class in Settings.py
# --------------------------REST-framework--------------------------
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticatedOrReadOnly'
],
"DEFAULT_AUTHENTICATION_CLASSES": (
"rest_framework_simplejwt.authentication.JWTAuthentication",
),
'DEFAULT_SCHEMA_CLASS': 'drf_spectacular.openapi.AutoSchema',
}
The last thing that could matter are my endpoints:
urlpatterns = [
path("", UserViewSet.as_view({"post": "create"}), kwargs={'quantity': 1}),
path("<int:quantity>/", UserViewSet.as_view({"post": "create"})),
path("", GetUserViewSet.as_view({"get": "list"})),
path("<int:pk>/", GetUserViewSet.as_view({"get": "retrieve"})),
path("<int:pk>/", UserViewSet.as_view({"put": "update", "delete": "destroy"})),
]
What I don't understand is that in other app where I have register functionality there is no such an error. I will show you this viewset:
class ApiUserViewSet(viewsets.GenericViewSet, mixins.CreateModelMixin):
serializer_class = ApiUserSerializer
permission_classes = [permissions.AllowAny]
queryset = ApiUser.objects.all()
#extend_schema(request=ApiUserSerializer, responses=TokenSerializer)
def create(self, request, *args, **kwargs):
api_user_serializer = self.get_serializer(data=request.data)
api_user_serializer.is_valid(raise_exception=True)
api_user = api_user_serializer.save()
refresh = RefreshToken.for_user(api_user)
token_serializer = TokenSerializer(
data={
"access": str(refresh.access_token),
"refresh": str(refresh)
}
)
token_serializer.is_valid(raise_exception=True)
headers = self.get_success_headers(token_serializer.data)
return Response(token_serializer.data, status=status.HTTP_201_CREATED, headers=headers)
If you have any idea what could be wrong please let me know!
Thank you

DRF Can't get data for restricted URLs

I'm using simple_JWT and I have a view that requires logged-in users.
When I try to send a request (tested with postman, curl, ...) I get 'Authentication credentials were not provided'.
views.py :
class CurrencyDetailAPIView(generics.RetrieveAPIView):
serializer_class = CurrencyDetailSerializer
lookup_field = "slug"
permission_classes = [IsAuthenticated]
settings.py :
REST_FRAMEWORK = {
"DEFAULT_AUTHENTICATION_CLASSES": [
"rest_framework_simplejwt.authentication.JWTAuthentication",
],
}
Get a recent token and make sure you are adding Authorization in the header with a value JWT {{your_token}}
Do not skip the space in between.

I keep getting 403 response error. I'm using django restframework with customized authentication method

Inspecting the header from postman i notice, the allowed method does not include the POST. I'm unable to make request for unauthenticated routes, i get 403.
class LoginUserAccountView(generics.CreateAPIView):
serializer_class = LoginSerializer
permission_classes = [permissions.AllowAny]
def create(self, request, *args, **kwargs):
serializer = LoginSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
try:
user = User.objects.get(email=request.data['email'])
if user.check_password(request.data['password']):
serialized_user = UserSerializer(user).data
access_token = generate_access_token(user)
return Response(data={'access_token': access_token,
'user': serialized_user}, status=status.HTTP_200_OK)
else:
return Response({'errors': 'Invalid credentials'})
except User.DoesNotExist:
return Response({'errors': 'No user with such email!'})
Here is what my REST_FRAMEWORK looks like the settings.py
REST_FRAMEWORK = {
'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema',
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.AllowAny',
),
# 'DEFAULT_AUTHENTICATION_CLASSES': (
# 'accounts.authentication.CustomJWTAuthentication',
# ),
'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',),
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
'PAGE_SIZE': 100
}
You should name your method create instead of post.
Method names reflect actions, not HTTP methods.
list - GET, multiple objects
retrieve - GET, single object using ID
create - POST
update - PUT
partial_update - PATCH
destroy - DELETE
Take a look at ViewSet example.

Authentication credentials were not provided with djangorestframework-jwt

I am trying to use django rest_framework_jwt. I can get it to generate a token but when i try and send it in the header to a protected view i get 'Authentication credentials were not provided.'
The format of the header I am sending is:
"Authorization": "Token SomeRandomToken"
settings.py
INSTALLED_APPS = [
...
rest_framework.authtoken
]
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
),
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
),
}
views.py
class UserList(mixins.ListModelMixin,
mixins.CreateModelMixin,
generics.GenericAPIView):
permission_classes = (permissions.IsAuthenticated,)
authentication_classes = (JSONWebTokenAuthentication,)
queryset = User.objects.all()
serializer_class = UserSerializer
From looking at the docs I would say you should remove the default TokenAuthentication from your
AUTHENTICATION_CLASSES
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
),
Also the header seems to have a different format:
Now in order to access protected api urls you must include the Authorization: JWT <your_token> header.