{ "detail": "CSRF Failed: CSRF token missing or incorrect." } - django

hello guys . I try to register a new Product in my app using DRF and Postman.
when I send a request I get this error.
the problem is just about my csrf_token.
I'll be thankfull if you help me.....
this is my view
class ProductViewSet(viewsets.ModelViewSet):
authentication_classes = (SessionAuthentication,TokenAuthentication)
permission_classes = [IsAdminUser]
queryset = ProductInfo.objects.all().order_by('-id')
serializer_class = ProductSerializer
filter_backends = (filters.SearchFilter,)
search_fields = ['title','code','owner__username']
I don't have any problem for GET request.

Django requires CSRF token in POST request by default. to avoid CSRF tokens.
Don't use SessionAuthentication as authentication class, coz, it will force you to add CSRF token.
If you still want to use SessionAuthentication then You can use it overrideing
def enforce_csrf(self, request): method
Try below this:
from rest_framework.authentication import SessionAuthentication
class CsrfExemptSessionAuthentication(SessionAuthentication):
def enforce_csrf(self, request):
pass
and use it in your views:
authentication_classes = (CsrfExemptSessionAuthentication ,TokenAuthentication)
If you want to use it globally, you can place it in your REST_FRAMEWORK settings.py file like this:
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.TokenAuthentication',
'myapp.path-to-file.CsrfExemptSessionAuthentication'
],
}
Please make sure you add correct file path in the REST_FRAMEWORK settings
To authenticate with the token.
You must request like this:
curl -X GET http://127.0.0.1:8000/api/example/ -H 'Authorization: Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b'
Also make sure you added this in your INSTALLED_APP:
INSTALLED_APPS = [
''''
'rest_framework',
'rest_framework.authtoken',
]
More details can be found here: https://www.django-rest-framework.org/api-guide/authentication/

Because you don't need csrf_token for GET method.
you can set your csrf_token in header like this:
X-CSRFToken: your_csrf_value
so instead of using Cookie add X-CSRFToken to your header in POSTMAN.

Related

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.

"rest_framework CSRF token failed" but it's already set in the request header as "X-CSRF-Token"

Already checked other topics and tried the answered solutions but the problem stays still. My put/post requests are return with an error.
detail: "CSRF Failed: CSRF token missing or incorrect."
Although I am sending CSRFToken inside the header axios.defaults.headers.common['X-CSRF-Token'] = CSRF_TOKEN;
And there it is the CSRF
By the way, in settings.py I set the authentication classes
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.TokenAuthentication',
'rest_framework.authentication.SessionAuthentication',
],
Additionally views.py
class ProjectViewSet(viewsets.ViewSet):
permission_classes = [IsAuthenticated | IsSuperUser]
# retrieve works without a problem
def retrieve(self, request, pk=None):
queryset = Project.objects.all().filter(company_user=self.request.user)
project = get_object_or_404(queryset, pk=pk)
serializer = ProjectSerializer(project)
return Response(serializer.data)
def update(self, request, pk=None):
# CSRF request problem
pass
def partial_update(self, request, pk=None):
# CSRF request problem
pass
and urls.py
router = DefaultRouter()
router.register('project', views.ProjectViewSet, basename='project')
urlpatterns = router.urls
Do I missing something here? Why do I keep having the CSRF error?
You should use X-CSRFToken instead of X-CSRF-Token

Getting "Authentication credentials were not provided." message when trying to access my ModelViewSet URL

I am creating an application using Django Rest Framework and using Token based authentication. I have a PlaceViewSet class inheriting from ModelViewSet. I want both list and retrieve to work even if there is no token sent by the user whereas create, destroy and update should be allowed only if the user has sent the Token. But I am getting Authentication credentials were not provided. for requests of all types. I also want to stick to the REST standard so that the list, retrieve, update, create, destroy comes under the same model view set.
In case if DRF does not allow any requests without Token if I have set my default authentication as TokenAuthentication then why I am able to access the signin and signup views?
You can change permission policy in settings.py
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.AllowAny'
],
}
If you want to add special permissions for methods.
Permission:
from rest_framework.permissions import IsAuthenticated, IsAdminUser
class SpecialPermissionMixin(object):
def get_permissions(self):
user_permission_list = ['list', 'retrieve', 'update']
admin_permission_list = ['destroy', 'create']
if self.action in user_permission_list:
permission_classes = [
IsAuthenticated,
]
elif self.action in admin_permission_list:
permission_classes = [
IsAdminUser,
]
else:
permission_classes = []
return [permission() for permission in permission_classes]
View:
class BlogViewSet(SpecialPermissionMixin, viewsets.ModelViewSet):
...

Unable to get user id with token by django rest framework?

I am using django Django=2.1.7 and rest framework djangorestframework=3.9.2 This is my url for login
path('rest-auth/', include('rest_auth.urls')),
After authentication I got token but I need user id too. I tried to override the post method of rest_framework.authtoken.views.py file with the following code
def post(self, request, *args, **kwargs):
serializer = self.serializer_class(data=request.data,
context={'request': request})
serializer.is_valid(raise_exception=True)
user = serializer.validated_data['user']
token, created = Token.objects.get_or_create(user=user)
context = {
'token': token.key,
'user': user.id
}
return Response({'context': context})
Please help me figure out how to get user id with the token. This is my college project.
Note: I find many answers on stack overflow but none is helpful.
Use this Django RestFramework token authentication in order to use authentication. Here you can see how to authenticate, however if you want to use token authentication by default for all views you should add it in settings.py file as :
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
...
'rest_framework.authentication.TokenAuthentication',
...
),
}
or you should add it manually to views which requires token authentication. And in this views you can get authenticated user as request.user or self.request.user.
from rest_framework.authentication import TokenAuthentication
class ViewSetName(ViewSet):
authentication_classes = [TokenAuthentication]

Django not recognizing my Token?

I'm using Django Rest Framework on the backend and an ember-cli app on the frontend. The authentication is working correctly, but there seems to be a hole somewhere in authorization.
# settings.py
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.AllowAny',
),
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
),
}
# views.py
class CurrentUserView(APIView):
"get the data for the current authenticatd user"
permission_classes = (IsAuthenticated,)
def get_queryset(self, request):
queryset = User.objects.filter(username=request.user.username)
return queryset
def get(self, request):
serializer = UserSerializer(request.user)
return Response(serializer.data)
When I make a request to this endpoint /v1/me/ it responds back with a 403. When I take off the permission class, I get back {"id":null,"username":"","is_active":false} because it doesn't know who I am.
Also, when I use the browsable API, the /v1/me URL works correctly.
On the Ember side of things, I login with my account and correctly get back my Token. In the request the Authorization: Token asdf1234asdf1234asdf1234 is being passed. I would think Django takes that token and knows who I am? Am I missing something?
Try something like
from rest_framework import authentication
class TokenAuthView(APIView):
authentication_classes = (authentication.TokenAuthentication,)
Then,
class CurrentUserView(TokenAuthView)
In the setting you need to add auth_token.
# settings.py
INSTALLED_APP = ('rest_framework.authtoken',)
You don't need to add the authentication_classes on every view.