Django REST: Authentication credentials were not provided - django

There are similar questions like this on StackOverflow which didn't solve my problem. I'm using Postman to test my APIs. For some reason, my token authorization is not working and it's showing the following message,
"detail": "Authentication credentials were not provided."
My settings.py:
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated',
],
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.TokenAuthentication',
],
}
These are my installed apps:
...
'rest_framework',
'rest_framework.authtoken',
'allauth',
'allauth.account',
'dj_rest_auth',
'dj_rest_auth.registration',
...
I spent some hours to find the problem but failed. Can anyone please help me with where might the problem be?

Related

Error with dj_rest_auth.jwt_auth.JWTCookieAuthentication

Everytime I run my server, I get this error on my terminal. I have tried researching about the cause but no luck with a response. This is the error below:
CreateProfileView: could not resolve authenticator <class 'dj_rest_auth.jwt_auth.JWTCookieAuthentication'>. There was no OpenApiAuthenticationExtension registered for that class. Try creating one by subclassing it. Ignoring for now.
This is my rest_framework settings:
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.TokenAuthentication',
'dj_rest_auth.jwt_auth.JWTCookieAuthentication',
],
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated',
],
'DEFAULT_SCHEMA_CLASS': 'drf_spectacular.openapi.AutoSchema',
}
Thanks.

Getting "CSRF token missing or incorrect" on obtain token request

We are using Django REST Framework and we are using user logins. From a web client we have a login screen and use obtain_auth_token from the REST Framework to obtain an api token. The web client uses XMLHttpRequest.
It starts out with working fine. The web client obtains a token using username+password and uses that token in the following API calls.
When I return the next day and open a new browser tab and try to log in I get a 403 Forbidden and the Django logs (and the body reply) says {"detail":"CSRF Failed: CSRF token missing or incorrect."}
I can see that the incoming request has a csrftoken cookie and a sessionid cookie. I can see the same cookies if I use the browser "Developer Tools". If I remove those two cookies, it works fine afterwards.
Also, if I launch a private browser window (= incognito), the web app works fine.
I am do not know why those cookies appear, when they appear exactly and why the REST framework do not like them.
I have two suspicions:
We also use the Django admin interface. Could it be that the login to the admin interface on the same domain will plant those cookies and somehow interfere with the REST Framework?
Something about time passes will make the problem appear? It seems to me that the problem does not appear until "the day after" if I clear the cookies. This might very well be other circumstances tricking me, like point 1 above.
Any suggestions on how to resolve this?
For reference, some snippes of our Django setting.py:
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'request_logging.middleware.LoggingMiddleware',
]
INSTALLED_APPS = [
'mybackend.apps.MybackendConfig',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django_cleanup.apps.CleanupConfig',
'rest_framework',
'rest_framework.authtoken',
'adminsortable',
'corsheaders',
'django_filters',
'storages',
]
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.DjangoModelPermissions'
],
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
'rest_framework.authentication.SessionAuthentication',
),
'DEFAULT_FILTER_BACKENDS': (
'django_filters.rest_framework.DjangoFilterBackend',
),
}
From urls.py:
from rest_framework.authtoken import views as restviews
...
urlpatterns = [
path('admin/', admin.site.urls),
url(r'^api/token-auth/obtain_auth_token', restviews.obtain_auth_token),
url(r'^api/', include(router.urls)),
]
Seems like the SessionAuthentication is the culprit. My guess is that is was added to be able to play with the REST interface from a browser for testing purposes.
So if I remove SessionAuthentication it seems to work.
Now the config looks like this:
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.DjangoModelPermissions'
],
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
# 'rest_framework.authentication.SessionAuthentication',
),
'DEFAULT_FILTER_BACKENDS': (
'django_filters.rest_framework.DjangoFilterBackend',
),
}

Django REST Framework BasicAuthentication is not applied as default authentication class

I have a Django REST Framework project and I added
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.BasicAuthentication',
]
}
to settings.py and I expect BasicAuthentication is applied to all pages as default but still it does not require any authentication to display the content. that is weird. Do I have to do something I did not do?
urls.py:
urlpatterns = [
path('admin/', admin.site.urls),
path('student/', include('blogapp.urls')),
path('api/', include('api.urls')),
path('api-auth/', include('rest_framework.urls')),
]
setting.py:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'blogapp',
]
blog_app/urls:
urlpatterns = [
path('', StudentView.as_view()),
]
views.py:
class StudentView(generics.ListCreateAPIView):
queryset = Student.objects.all()
serializer_class = StudentSerializer
UPDATE 1:
Also per-view authentications not work!
UPDATE 2:
This is my project source code.
Authentication is not the same as permission. You'll also need to add a default permission class if you require all users to be authenticated (using one of the authentication methods you wish to use):
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.BasicAuthentication',
],
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated',
],
}
Also, make sure you're testing the right view (/api/list/). Your project (as you linked) has two StudentViews, one of which is a DRF view, the other (/student/) isn't. The latter will not be aware of DRF configuration.

How to use axios to post to my Django Rest server?

I am getting a 403 error when trying to post to my Django server from my frontend mobile app. However, it works totally fine when I post with the form on the browser.
I managed to register once using my frontend mobile app, but ever since then, I get this 403 error. I've tried both signing up and logging in.
Here is the error I get in my Django backend terminal:
Bad Request: /rest-auth/registration/
[16/Aug/2021 14:51:37] "POST /rest-auth/registration/ HTTP/1.1" 403 58
Here is my settings.py file:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'rest_framework.authtoken',
'rest_auth',
'django.contrib.sites',
'allauth',
'allauth.account',
'rest_auth.registration',
'users',
]
SITE_ID = 1
....
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.BasicAuthentication',
),
}
ACCOUNT_EMAIL_VERIFICATION = 'none'
Here is my front end (register.js):
axios
.post("http://127.0.0.1:8002/rest-auth/registration/", {
username: "tester1234#gmail.com",
email: "tester1234#gmail.com",
password1: "tester1234#gmail.com",
password2: "tester1234#gmail.com",
})
What am I doing wrong? I just want users to be able to register, log in, and log out of my app.
The issue was that I had logged in, and then was not providing the key.
To solve this, I created a logout button, then added a mechanism to save the key and use it in the header.

Django rest-auth registration. How to return user_id with the key when using token authentication

I am using Djando rest_auth.registration.
My corresponding entry in urls.py is
url(r'^rest-auth/registration/', include('rest_auth.registration.urls'))
My authentication class is rest_framework.authentication.TokenAuthentication
This rest API call works perfectly well.
When I register via this API I get the below response.
{
"key": "3735f13cd69051579156f98ffda338a2d7a89bb5"
}
I also want to include the user_id field in the response. How do I go about doing that. I tried extending the method get_response_data from class RegisterView(CreateAPIView): but unable to do so. Can someone please advise the best practice to achieve this. Code would be ideal. Thanks.
I want to use the rest-auth/registration/ url provided out of box by rest_auth.registration. I do not want to create a separate new URL for this.
My Settings.py as follows
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.sites',
'sdAPI.apps.SdapiConfig',
'rest_framework',
'rest_framework.authtoken',
'rest_auth',
'rest_framework_swagger',
'rest_auth.registration',
'allauth',
'allauth.account',
'allauth.socialaccount',
'allauth.socialaccount.providers.facebook',
'allauth.socialaccount.providers.google',
'django_extensions',
]
# auth and allauth settings
LOGIN_REDIRECT_URL = '/'
SOCIALACCOUNT_QUERY_EMAIL = True
SOCIALACCOUNT_PROVIDERS = {
'facebook': {
'SCOPE': ['email', 'publish_stream'],
'METHOD': 'oauth2' # instead of 'oauth2'
}
}
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
),
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
)
}
SITE_ID = 1
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
REST_SESSION_LOGIN = False
My urls.py as follows
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^user/(?P<pk>[0-9]+)/$', views.UserDetail.as_view()),
url(r'^rest-auth/', include('rest_auth.urls')),
url(r'^rest-auth/registration/',include('rest_auth.registration.urls')),
]
I think you only need to override the TOKEN_SERIALIZER option in your REST_AUTH_SERIALIZERS configuration.
from rest_framework.authtoken.models import Token
class TokenSerializer(serializers.ModelSerializer):
class Meta:
model = Token
fields = ('key', 'user')
Then, set it in your settings.py as shown in the docs,
REST_AUTH_SERIALIZERS = {
'LOGIN_SERIALIZER': 'path.to.custom.LoginSerializer',
'TOKEN_SERIALIZER': 'path.to.custom.TokenSerializer',
...
}