Session is not storing variables - Django - django

I've been having trouble storing my tokens on session.
I've found few solutions on stackoverflow but none of them worked.
currently, I store user's token when client send a POST request to /api/login
and here is my views logic
request.session['token'] = auth.token.key
request.session.modified = True
I'm 100% sure auth.token.key is not None and the logic stores just fine.
but when it comes to /api/update (some sample api),
I always get None
here is how I get the Item from session:
print(request.session.get('token'))
** The Code above always returns None**
I read the Django docs. I set both the session middleware and session app:
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',
'user'
]
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 = (
'user.auth.AuthBackend',
'django.contrib.auth.backends.RemoteUserBackend',
'django.contrib.auth.backends.ModelBackend',
)
I've done all the migrations.django_session table exists.
EDITED:
login view:
I have custome authentication backend
#api_view(['POST'])
def login(request):
# convert json data into dictionary
data = get_data(request)
print(request.session.get('token'))
auth = authenticate(
email = data['email'],
password = data['password']
)
if auth:
# store user's token into sesion
request.session['token'] = auth.token.key
print(request.session['token'])
user = UserModelSerializer(auth.user)
return Response(
user.data,
status = status.HTTP_200_OK
)
else:
return Response(
message("user doestn't exist | incorrect password"),
status = status.HTTP_403_FORBIDDEN
)
Update View (where I can't get the session data):
#api_view(['POST'])
def update(request):
print(request.session.get('token'))
return Response("its ok.")

Related

Django + Vue 403 Forbidden Error On axios.get

I'm trying to log the user but the Django rest API can't see the current jwt token of the logging user and I'm getting a 403 error. The API is working fine on the Postman with all the Authentication aspects. I have tried some advised solutions but they don't seem to work.
Attempt 1
axios.defaults.headers.common["authorization"] =
"Bearer " + localStorage.getItem("jwt");
await axios.get(api-link)
Attempt 2
axios.defaults.xsrfHeaderName = "X-CSRFTOKEN";
axios.defaults.xsrfCookieName = "csrftoken";
axios.defaults.withCredentials = true;
await axios.get(api-link)
Attempt 3
await axios.get(api-link.{
{
headers:{header stuff}
},
{withCredentials: true}
)
(Basically adding headers and credentials inside the get request.)
Django settings.py
I couldn't find a standard for this, currently I'm using this one for testing:
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',
'corsheaders',
'users',
]
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',
]
CORS_ALLOW_ALL_ORIGINS = True
CORS_ALLOW_CREDENTIALS = True
CORS_ALLOWED_ORIGINS = ['http://127.0.0.1:8000', 'http://localhost:8000']
REST_FRAMEWORK = {
'DEFAULT_PARSER_CLASSES': [
'rest_framework.parsers.JSONParser',
]
}
CSRF_COOKIE_NAME = "XSRF-TOKEN"

Django, request.user prints AnonymousUser, even if i logged in

views.py
class StorageView(viewsets.ModelViewSet):
serializer_class = StorageSerializer
def get_queryset(self):
if self.request.user.is_authenticated:
user = self.request.user
queryset = Storage.objects.filter(username=user.username)
return queryset
else:
print(self.request.user)
return []
urls.py
from django.urls import path, include
from django.urls import re_path as url
urlpatterns = [
path('auth/', include('rest_auth.urls')),
path('auth/register/', include('rest_auth.registration.urls'))
]
settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
# CORS
'corsheaders',
# REST
'rest_framework',
'rest_framework.authtoken',
'rest_auth',
'rest_auth.registration',
'django.contrib.sites',
# App
'backend'
]
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware',
'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',
]
SITE_ID = 1
ACCOUNT_EMAIL_REQUIRED = True
ACCOUNT_USERNAME_REQUIRED = False
ACCOUNT_SESSION_REMEMBER = True
ACCOUNT_AUTHENTICATION_METHOD = 'email'
ACCOUNT_UNIQUE_EMAIL = True
REST_FRAMEWORK = {
'DATETIME_FORMAT': "%m/%d/%Y %I:%M%P",
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.TokenAuthentication',
],
}
I logging in via form or api, but is_authenticated method don't see me
Login via api
postman screenshot
Condition in get_queryset() function in views.py always evaluates to false, even if i logged in it keeps printing "AnonymousUser", why? How to check if user is logged in, in my case?
Provide
permission_classes = [IsAuthenticated]
in your views.
and pass
Authorization token with every request
axios
.get(
`http://localhost:8000/anything`,
{
headers: {
Authorization: `Token ${token}`,
},
}
)

Django CSRF missing or Sessions middleware required

When trying to create a django(2) rest framework api, I keep getting this error.
Forbidden (CSRF token missing or incorrect.): /login/
After doing some research the problem might be with sessions authentication which I don't really need since I will be replying on token based auth. When I try to remove some of the session auth from my settings I end up getting this.
AssertionError: The Django authentication middleware requires session middleware to be installed. Edit your MIDDLEWARE setting to insert 'django.contrib.sessions.middleware.SessionMiddleware' before 'django.contrib.auth.middleware.AuthenticationMiddleware'.
Settings.py snippet
INSTALLED_APPS = [
# API (v1)
'apiV1.v1.accounts.apps.AccountsConfig',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
# Requirements
'corsheaders',
'rest_framework',
'rest_framework.authtoken',
]
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware',
'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',
]
ROOT_URLCONF = 'apiV1.urls'
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticatedOrReadOnly',
),
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.BasicAuthentication',
'rest_framework.authentication.TokenAuthentication',
# 'rest_framework.authentication.SessionAuthentication',
),
}
Views.py
from django.contrib.auth import authenticate
from django.shortcuts import get_object_or_404
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from apiV1.v1.accounts.models.user import User
from apiV1.v1.accounts.serializers.user import UserSerializerLogin
# login
class LoginView(APIView):
authentication_classes = ()
permission_classes = ()
#staticmethod
def post(request):
"""
Get user data and API token
"""
user = get_object_or_404(User, email=request.data.get('email'))
user = authenticate(username=user.email, password=request.data.get('password'))
if user:
serializer = UserSerializerLogin(user)
return Response(serializer.data)
return Response(status=status.HTTP_400_BAD_REQUEST)
If you don't need session for authentication you have to use token authentication.
Here is the example of view
from rest_framework.authtoken.models import Token
from rest_framework.authtoken.views import ObtainAuthToken
from rest_framework.response import Response
class Login(ObtainAuthToken):
def post(self, request, *args, **kwargs):
"""
---
serializer: AuthTokenSerializer
"""
serializer = self.serializer_class(data=request.data)
serializer.is_valid(raise_exception=True)
user = serializer.validated_data['user']
token, created = Token.objects.get_or_create(user=user)
return Response({
'pk': user.pk,
'first_name': user.first_name,
'last_name': user.last_name,
})
Or you can use JWT authentication.
Here are some helpful links for you.
http://www.django-rest-framework.org/api-guide/authentication/
http://getblimp.github.io/django-rest-framework-jwt/

Django Request Session on anonymous users

I have the following problem:
I'm using the Django Rest framework with anonymous users (i don't have users in my application) and in my views file when i try to modify the request.session variable, the value is not persistent in all views. I have two different class based views:
def post(self, request):
...
request.session["instances"] = serializer.data
request.session.modified = True
...
return Response(data, status=status.HTTP_200_OK)
def get(self, request, page):
...
print request.session["instances"]
...
return Response(data, status=status.HTTP_200_OK)
On the second view i get a key error, basically the key "instances" doesn't exist. This is my settings file:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'corsheaders',
]
MIDDLEWARE = [
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.security.SecurityMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'corsheaders.middleware.CorsMiddleware',
]
SESSION_SAVE_EVERY_REQUEST = True
############
# SESSIONS #
############
# Cache to store session data if using the cache session backend.
SESSION_CACHE_ALIAS = 'default'
# Cookie name. This can be whatever you want.
SESSION_COOKIE_NAME = 'sessionid'
# Age of cookie, in seconds (default: 2 weeks).
SESSION_COOKIE_AGE = 60 * 60 * 24 * 7 * 2
# A string like ".example.com", or None for standard domain cookie.
SESSION_COOKIE_DOMAIN = None
# Whether the session cookie should be secure (https:// only).
SESSION_COOKIE_SECURE = False
# The path of the session cookie.
SESSION_COOKIE_PATH = '/'
# Whether to use the non-RFC standard httpOnly flag (IE, FF3+, others)
SESSION_COOKIE_HTTPONLY = True
# Whether a user's session cookie expires when the Web browser is closed.
SESSION_EXPIRE_AT_BROWSER_CLOSE = False
# The module to store session data
SESSION_ENGINE = 'django.contrib.sessions.backends.db'
# Directory to store session files if using the file session module. If None,
# the backend will use a sensible default.
SESSION_FILE_PATH = None
# class to serialize session data
SESSION_SERIALIZER = 'django.contrib.sessions.serializers.JSONSerializer'
#########
# CACHE #
#########
# The cache backends to use.
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
}
}
CACHE_MIDDLEWARE_KEY_PREFIX = ''
CACHE_MIDDLEWARE_SECONDS = 600
CACHE_MIDDLEWARE_ALIAS = 'default'
I haven't been able to store data on request.session successfully, i tried checking if the session has a session_key but it prints None, so i created a session on the first view with session_id = request.session._get_or_create_session_key() but still on the second view it doesn't exist anymore (session_key is None). Anybody here had this problem before?

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">