DRF Token Authentication - not able to retrieve Token on Postman - python

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

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

Token Authentication Not Working on Django Rest Framework

I have a Django application, which I am using DRF for my API with Session, and Token authentication. I have rest_framework, and rest_framework.authtoken in my installed apps. I have migrated my database and can create tokens for users in the Django Admin. I know all of this is working because I am accessing rest_framework.auth_token's obtain_auth_token view for returning a token when user data is submitted in a POST request, and receive one back. When I try to make a GET request to a view function in my app that has TokenAuthentication on its viewset, it keeps returning.
{"detail":"Authentication credentials were not provided."}
Settings File
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
# My Apps
'rest_framework',
'rest_auth',
'rest_framework.authtoken',
]
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.TokenAuthentication',
],
}
URLS
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from rest_framework.authtoken import views
from api.views.some_model import MyViewSet
urlpatterns = [
path('', include(router.urls)),
path('rest-auth/', include('rest_auth.urls')),
path('api-token-auth/', views.obtain_auth_token)
]
Viewset
from rest_framework.viewsets import ModelViewSet
from rest_framework.authentication import SessionAuthentication, TokenAuthentication
from rest_framework.permissions import IsAuthenticated
from some_app.models import SomeModel
from api.serializers.exams import SomeModelSerializer
class ExamViewSet(ModelViewSet):
permission_classes = (IsAuthenticated,)
authentication_classes = (TokenAuthentication, SessionAuthentication)
queryset = SomeModel.objects.all()
serializer_class = SomeModelSerializer
Python Script to Get Response
import requests
import json
data = {
"username": "myemail#gmail.com",
"password": "password124"
}
url = "http://localhost:8002/api/v1/api-token-auth/"
response = requests.post(url, data=data)
token = json.loads(response.text).get('token')
if token:
token = f"Token {token}"
headers = {"Authentication": token}
response = requests.get("http://localhost:8002/api/v1/model/", headers=headers)
print(response.text)
else:
print('No Key')
Header name should be Authorization not Authentication:
headers = {"Authorization": token}
response = requests.get("http://localhost:8002/api/v1/model/", headers=headers)
The token should be provided in the header like
-H "Authorization: Token 8fa36c01df3bb9ed31fc2329c53a9fe2cac72966"
Authorization:prefix YourToken
If you are using JWT authentication then your request header should look like
Authorization: JWT your-token-here
or
Authorization: Bearer your-token-here

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 JWT "Authentication credentials were not provided."}

I am trying to write a simple API that uses JWT tokens to authenticate.
My settings.py:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
]
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
'rest_framework.permissions.IsAdminUser'
),
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.BasicAuthentication',
),
'PAGE_SIZE': 10
}
And my View looks like this:
class ExampleView(APIView):
permission_classes = (IsAuthenticated,)
authentication_classes = (JSONWebTokenAuthentication,)
def get(self, request, format=None):
return JsonResponse({"username":str(request.user)})
Which really does nothing, but I don't even get there. I have registered the JWT Token provider as in the documentation with url(r'^api-token-auth/', obtain_jwt_token) and I receive a token when I call this endpoint.
However, when I then make a request against my APIView (which contains the header Authorization: JWT <my_token> I always receive the following error:
[Response]: 403 [Data]: {"detail":"Authentication credentials were not provided."}
What am I missing? Thanks in advance!
If you are using apache as web server then add the following in apache httpd.conf file:
WSGIPassAuthorization On
This worked for me.

Django Rest - CSRF Failed: CSRF token missing or incorrect

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?

Categories

Resources