skip to Main Content

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


  1. 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.

    Login or Signup to reply.
  2. 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:

    class IsBusinessOwnerOrReadOnly(BasePermission):
        """
        The request is authenticated and is the same user as the business owner, or is a read-only request.
        """
    
        def has_permission(self, request, view):
            return bool(
                request.method in SAFE_METHODS or
                request.user and
                request.user.is_authenticated
            )
    
        def has_object_permission(self, request, view, obj):
            if not isinstance(obj, Business):
                raise Exception('This object is not a Business class instance')
    
            return request.method in SAFE_METHODS or obj.owner.pk == request.user.pk
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search