it’s my first question of SO. please, point out where I need to clarify at any point.
Im building a django back-end, react front-end app. I have this view that returns a 401 response whenever I try to directly access it on the front-end, even when a user is logged in. I have access to my other views but this one. It works fine in the drf browsable API.
I’m using both Session and TokenAuthentication in my default authentication classes.
Here’s my base settings.py
import os
from decouple import config
import datetime
ALLOWED_HOSTS = []
BASE_DIR =
os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(__file__)), os.pardir))
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'whitenoise.runserver_nostatic',
'django.contrib.staticfiles',
'django.contrib.sites',
'rest_framework',
'rest_auth',
'rest_framework.authtoken',
'dj_rest_auth',
'allauth',
'allauth.account',
'allauth.socialaccount',
'corsheaders',
'djoser',
'dj_rest_auth.registration',
'channels',
'core'
]
SITE_ID = 1
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
'whitenoise.middleware.WhiteNoiseMiddleware', # Whitenoise Middleware
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'home.urls'
AUTH_USER_MODEL = 'core.User'
REST_AUTH_REGISTER_SERIALIZERS = {
'REGISTER_SERIALIZER': 'core.serializers.UserSerializer'
}
ACCOUNT_ADAPTER = 'core.adapter.CustomAccountAdapter'
AUTHENTICATION_BACKENDS = [
'django.contrib.auth.backends.ModelBackend',
'allauth.account.auth_backends.AuthenticationBackend',
]
REST_FRAMEWORK = {
'TEST_REQUEST_DEFAULT_FORMAT': 'json',
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated',
'rest_framework.permissions.AllowAny',
],
'DEFAULT_AUTHENTICATION_CLASSES': [
#'rest_framework_simplejwt.authentication.JWTAuthentication',
'rest_framework.authentication.TokenAuthentication',
'rest_framework.authentication.SessionAuthentication',
# 'dj_rest_auth.jwt_auth.JWTCookieAuthentication'
],
"DEFAULT_PARSER_CLASSES": ["rest_framework.parsers.JSONParser"],
}
REST_USE_JWT = False
# JWT_AUTH_COOKIE = 'core.auth'
SIMPLE_JWT = {
'ACCESS_TOKEN_LIFETIME': datetime.timedelta(minutes=5),
'REFRESH_TOKEN_LIFETIME': datetime.timedelta(days=1),
'USER_ID_CLAIM': 'id',
}
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates'),
os.path.join(BASE_DIR, 'build')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.template.context_processors.media',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
ASGI_APPLICATION = 'home.routing.application'
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'build', 'static')
STATICFILES_DIRS = []
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
REDIS_URL = config('REDIS_URL', 'redis://localhost:6379')
CHANNEL_LAYERS = {
'default': {
'BACKEND': 'channels.redis.core.RedisChannelsLayer',
'CONFIG': {'hosts': [REDIS_URL]},
},
}
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = False
DJOSER = {
'PASSWORD_RESET_CONFIRM_URL': '#/password/reset/confirm/{uid}/{token}',
'USERNAME_RESET_CONFIRM_URL': '#/username/reset/confirm/{uid}/{token}',
'ACTIVATION_URL': '#/activate/{uid}/{token}',
'SEND_ACTIVATION_EMAIL': True,
'SERIALIZERS': {},
}
ACCOUNT_EMAIL_REQUIRED = True
ACCOUNT_AUTHENTICATION_METHOD = "username_email"
#ACCOUNT_EMAIL_VERIFICATION = "mandatory"
# OLD_PASSWORD_FIELD_ENABLED = True
# PASSWORD_RESET_TIMEOUT_DAYS = 1
# ACCOUNT_EMAIL_CONFIRMATION_EXPIRE_DAYS = 2
Here’s the view where I first noticed the error
class StoreDetailView(RetrieveAPIView):
# Should return an object of all the attributes of a store if request.user is owner of store
serializer_class = StoreSerializer
permission_classes = (IsAuthenticated, )
def get_object(self):
try:
user = self.request.user
return Store.objects.get(owner=user)
# store = Store.objects.get(owner=self.request.user)
# return store
except ObjectDoesNotExist:
raise Http404('This store was not found for this user')
2
Answers
Check if the session_id or token is being passed in the request’s headers.
This article explains in great detail on how to use Token based authentication with DRF.
Check if you have implemented any of the
permission_classes
, the functions for permissions requests exactly, if you dont allow GET method, the user cant read the object.Here’s and example I have implemented for my custom permissions: