Django Rest - CSRF Failed: CSRF token missing or incorrect - python

Got a weird scenario. I am on the Django Rest browser api with a logged in user.
When I update it is okay. But when I try to create a user, this error shows:
CSRF Failed: CSRF token missing or incorrect.
it also auto logged out me every single time.
In views.py, I already have added
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
Still same error and scenario.
In my settings.py:
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.SessionAuthentication',
),
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.AllowAny',
],
}
Anyone experienced this?

Related

"Authentication details were not provided." Django jwt

I've created a view for getting details of the user's profile.
user_views.py
#api_view(['GET'])
#permission_classes([IsAuthenticated])
def getUserProfile(request):
   user = request.user
    serializer = UserSerializer(user, many=False)
   return Response(serializer.data)
urls.py
urlpatterns = [
path("/users/profile/", uv.getUserProfile, name="get-user-profile")
]
serializers.py
class UserSerializer(serializers.ModelSerializer):
    name = serializers.SerializerMethodField(read_only=True)
    isAdmin = serializers.SerializerMethodField(read_only=True)
    class Meta:
        model = User
        fields = ['id', 'username', 'email', 'name', 'isAdmin']
    def get_id(self, obj):
        return obj.id
    def get_isAdmin(self, obj):
        return obj.is_staff
    def get_name(self, obj):
        name = obj.first_name
        if name == '':
            name = obj.email
        return name
class UserSerializerWithToken(UserSerializer):
    token = serializers.SerializerMethodField(read_only=True)
    class Meta:
        model = User
        fields = ['id', 'username', 'email', 'name', 'isAdmin', 'token']
    def get_token(self, obj):
        token = RefreshToken.for_user(obj)
        return str(token.access_token)
I'm sending a get request through post man and sending a authorization header with Bearer <token>. And got
{
"detail": "Authentication details were not provided."
}
Using django-rest-framework and django-rest-framework-simplejwt.
Figured it out like after a bit. Needed to add
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework_simplejwt.authentication.JWTAuthentication',
],
}
to settings.py

Is there a way to login in django rest api in browser without UI?

I'm doing backend project in which I need to do an API without any UI. In this API there's no registration (only by admin UI), but I need a way to log in, because I need some "pages" to be only for logged in users.
I set up token authentication, each user has their token created.
Is there a simple way to make some login "form" with serializer? I mean "page" in which there is only two fields (for username and password) and ability to POST this to get authenticated and then go back to "login only pages"?
I recommend to try DjangoREST browsable API: https://www.django-rest-framework.org/topics/browsable-api/. It is included into DRF, so you do not need to install any extras. In order to use the browsable API, just type the endpoint url into your browser. If you are using ModelSerializers, then forms for data input will be generated automatically, otherwise you will have to enter data as a JSON.
add to settings.py
REST_FRAMEWORK = {
'DEFAULT_PARSER_CLASSES': (
'rest_framework.parsers.JSONParser',
'rest_framework.parsers.FormParser',
'rest_framework.parsers.MultiPartParser'
),
'DEFAULT_RENDERER_CLASSES': (
'rest_framework.renderers.JSONRenderer',
'rest_framework.renderers.BrowsableAPIRenderer',
),
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.SessionAuthentication',
),
}
add to urls.py
urlpatterns = [
...
path('api-auth/', include('rest_framework.urls', namespace='rest_framework')),
...
]

DRF Token Authentication - not able to retrieve Token on Postman

I'm trying to retrieve a token for the user using the following request through Postman.
http://127.0.0.1:8000/api-token-auth/
JSON Body -
{
"username": "user1",
"password": "testpass"
}
The following is the error response -
{
"detail": "CSRF Failed: CSRF token missing or incorrect."
}
I've checked the instructions provided in the official DRF Authentication document as well as various other question posts and implemented the following code.
settings.py
INSTALLED_APPS = [
...
'rest_framework',
'rest_framework.authtoken',
'allauth',
'allauth.account',
'allauth.socialaccount',
'rest_auth',
'rest_auth.registration',
....
]
AUTH_USER_MODEL = 'users.CustomUser'
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
'rest_framework.authentication.SessionAuthentication',
),
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
)
}
signals.py
#receiver(post_save, sender=settings.AUTH_USER_MODEL)
def create_auth_token(sender, instance=None, created=False, **kwargs):
if created:
Token.objects.create(user=instance)
urls.py
from django.contrib import admin
from django.urls import include, path, re_path
from django_registration.backends.one_step.views import RegistrationView
from rest_framework.authtoken import views as authtoken_views
urlpatterns= [
path('admin/', admin.site.urls),
path("accounts/",
include("django_registration.backends.one_step.urls")),
path("accounts/",
include("django.contrib.auth.urls")),
path("api-auth/",
include("rest_framework.urls")),
path("api-token-auth/", authtoken_views.obtain_auth_token, name="api-token-auth"),
path("api/rest-auth/",
include("rest_auth.urls")),
path("api/rest-auth/registration/",
include("rest_auth.registration.urls")),
]
Have I missed something?
Found the issue.
The issue was not with the implementation, rather it was with Postman. Postman interceptor had retrieved cookies from the browser and had stored the CSRF Token with it. This token was automatically added to the request headers and hence, django tried to authenticate this request from Session Authentication which naturally should fail.
The solution-
Open the Postman cookies and Delete the CSRF Token.
PS- A curl request can always help in verifying such issues

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',
]
}

Django and React getting 403 forbidden

I've used create-react-app combined with Django Rest Framework to make a small site. Everything works perfectly when I use npm start and hit the Django API from one port to another. When I npm build the static react files and serve them from within the Django app, however, I get 403 forbidden when hitting a number of endpoints. I think it has something to do with CSRF, but I can't figure out what.
I serve the static files from views.py:
#api_view(['GET'])
def serve_html(request):
try:
with open(os.path.join(REACT_APP_DIR, 'build', 'index.html')) as f:
return HttpResponse(f.read())
except FileNotFoundError:
return HttpResponse(
"""
This URL is only used when you have built the production
version of the app. Visit http://localhost:3000/ instead, or
run `yarn run build` to test the production version.
""",
status=501,
)
My urls.py contains the catchall for the static files at the bottom:
urlpatterns = [
# ..all api paths
url(r'^', serve_html, name='serve_html'),
]
I use TokenAuthentication and SessionAuthentication:
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
'rest_framework.authentication.SessionAuthentication',
)
}
And the api requests that require users to be logged in have the following decorators:
#authentication_classes((SessionAuthentication, TokenAuthentication))
#permission_classes((IsAuthenticated,))
Addendum: I notice that when running it cross-origin, there is no sessionid cookie (and things work), but when I try to host react files on same-origin, there is a sessionid cookie (and 403 Forbidden is returned).
Sorry for the open-endedquestion, but I'm at my wit's end here; I really don't know why it's not working.
You do not require the SessionAuthentication class since you are using a token-based HTTP Authentication scheme. This should do the trick:
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
)
}
Hope this helps.

Categories

Resources