request.user.is_authenticated is always false in Django rest framework - django

I am using allauth for authentication in drf. I was able to register new users and login with the credentials.
The login api return response something like this:
{
"key" : "<some token>"
}
Now I have 1 more API the code for which is
from django.http import HttpResponse
def lol(request):
if request.user.is_authenticated:
return HttpResponse("Authenticated")
else:
return HttpResponse("Not Authenticated")
But this is always returning not authenticated
my api call look like this
Here is the list of installed apps in 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.authtoken',
'rest_auth',
'django.contrib.sites',
'allauth',
'allauth.account',
'rest_auth.registration',
'api.user',
'api.activity',
]

It seems you're using functional views? If so did you add #api_view decorator to the view?
If so did you add authentication_classes=[TokenAuthentication] keyword argument? That's imperative to make token Auth work.
Either that or set the following in settings.py:
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.TokenAuthentication'
]
}

Related

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.

TypeError: 'BasePermissionMetaclass' object is not iterable in django rest framework

i looked at other questions regarding this issue and their problems were in the REST_FRAMEWORK = ... values in settings.py file . is there any error in mine ?
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'api_basic',# this is my app that uses authtokens
'rest_framework',
'rest_framework.authtoken',
]
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.TokenAuthentication',
],
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated',
],
}
view:
#api_view(['GET', ])
#permission_classes(IsAuthenticated)
def api_hero(request, name):
try:
character = Hero.objects.get(name=name)
except:
return Response(status=status.HTTP_404_NOT_FOUND)
serializer = serializers.HeroSerializer(character)
return Response(serializer.data)
so i found the answer my self . the problem was in view
#permission_classes(IsAuthenticated)
here permission classes arguments should be a tuple.
so:
#permission_classes((IsAuthenticated,))
is the way to go.
'DEFAULT_PERMISSION_CLASSES': ('rest_framework.permissions.AllowAny',)
Add the following line to your settings.py.
It turns out omitting the last comma from the tuple will throw an error because 'DEFAULT_PERMISSION_CLASSES' expects a tuple

Django request.user is anonymous in views without login_required decorator

I am working on a Django (v2.0) app with django-allauth as auth backend. I'll explain my problem in steps:
User logs in -> user redirected to home page (can't access home page without login)
In the home page (after logging in), several calls are made for a particular view in the server.
Ex: https://mywebsite.com/api/getstuff/123
Problem: getstuff returns/prints data that is intended for a user who is NOT logged in.
getstuff is defined in urls.py as:
url(r'^api/getstuff/(?P<hash_code>[a-zA-Z0-9]{3})$', views.getstuff, name='getstuff')
in views.py: (views.getstuff)
#csrf_protect
#ensure_csrf_cookie
def getstuff(request,hash_code):
if request.user.is_authenticated:
#do stuff....
print('user is authenticated!')
return HttpResponse(hash_code+'foo-auth')
else:
#do other stuff..
print('user is NOT authenticated')
return HttpResponse(hash_code+'foo-un_auth')
I only see user is NOT authenticated being printed in my case. Shouldn't the output be user is authenticated since the user is already logged in? the request.user object is an AnonymousUser object. All the requests I make are from https.
few configurations from settings.py:
CSRF_USE_SESSIONS = True
CSRF_COOKIE_SECURE = True #tried removing this, still same result as above
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.sites',
'django_extensions',
'django.contrib.sitemaps',
'mysite.core',
'bootstrapform',
'allauth',
'allauth.account',
'allauth.socialaccount',
'allauth.socialaccount.providers.facebook',
'allauth.socialaccount.providers.google',
'allauth.socialaccount.providers.github',
'allauth.socialaccount.providers.twitter',
'embed',
'channels',
'djcelery'
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
AUTHENTICATION_BACKENDS = (
"allauth.account.auth_backends.AuthenticationBackend",
)
I tried clearing cache before accessing the website and logging in - still same result.
Am I missing something? What could be the problem?
Your use of if request.user.is_authenticated: is fine. Change the image src tag to use the domain that you logged into.
<img src="/api/getstuff/123">

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

Django OAuth Toolkit

I am trying to use oauth2 authentication using django oauth toolkit. I got the following exception :
Could not import 'oauth2_provider.ext.rest_framework.OAuth2Authentication' for API setting 'DEFAULT_AUTHENTICATION_CLASSES'
My settings.py file looks like :
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'adaccounts',
'corsheaders',
'clients',
'Gen42Backend',
'djcelery',
'oauth2_provider'
)
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'oauth2_provider.ext.rest_framework.OAuth2Authentication',
)
}
In case anyone has the same problem.
Replace:
oauth2_provider.ext.rest_framework.OAuth2Authentication
With:
oauth2_provider.contrib.rest_framework.OAuth2Authentication