I've a django application which runs on gunicorn behind nginx proxy.
When users log in, I redirect them to a single page application which is developed by Angular.
I'm using @login_required decorator for all functions used in SPA.
While using the application, one random function call suddenly is sent as AnonymousUser, so the @login_required decorator does not work, so I log out the user, or show error.
I'm using a custom user profile, with session engine as cached_db run by memcached & postgresql behind pgbouncer
My authentication relative settings are as follows: ps: get_env_variable() function gets the variable from the OS environment.
AUTH_USER_MODEL = 'main.User'
AUTH_PROFILE_MODULE = 'main.User'
INSTALLED_APPS = [
'django.contrib.auth',
'django.contrib.sessions',
***
]
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.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
#Sessions
SESSION_SAVE_EVERY_REQUEST = True
SESSION_COOKIE_NAME = 'sesid'
SESSION_COOKIE_PATH = '/'
SESSION_COOKIE_DOMAIN = 'domain.com'
SESSION_COOKIE_SECURE = True
SESSION_COOKIE_AGE = 1800
SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'
CSRF_COOKIE_NAME = 'csrftkn'
CSRF_COOKIE_PATH = '/'
CSRF_COOKIE_SECURE = True
CSRF_COOKIE_HTTPONLY = True
CSRF_COOKIE_DOMAIN = 'domain.com'
CSRF_COOKIE_AGE = 1800
CSRF_TRUSTED_ORIGINS = ['domain.com']
SECURE_CONTENT_TYPE_NOSNIFF = True
SECURE_BROWSER_XSS_FILTER = True
X_FRAME_OPTIONS = "SAMEORIGIN"
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': get_env_variable("DATABASE_NAME"),
'USER': get_env_variable("DATABASE_USER"),
'PASSWORD': get_env_variable("DATABASE_PASSWORD"),
'HOST': get_env_variable("DATABASE_HOST"),
'PORT' : get_env_variable("DATABASE_PORT"),
'CONN_MAX_AGE': None,
'OPTIONS': {
'sslmode': 'verify-full',
}
}
}
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
'LOCATION': "127.0.0.1:11211",
}
}
Funny thing is, I'm using the same settings for another Django application, which works perfect. What could be the reason for Django sending one request as AnonymousUser? I've never seen this before..
Also, if I remove the @login_required decorator, the next function call is sent as the logged user. So 1 out of 15-20 requests is sent as AnonymousUser. Which is really strange..
My sentry logs showed up a strange issue which is;
DjangoUnicodeDecodeError: 'utf8' codec can't decode byte 0xdd in position 12: invalid continuation byte. You passed in 'HTTP_CONNECT\xddON' (<type 'str'>
When I dug into the situation, it turns out that in one of my functions I was using locale and set the locale to tr_TR. After setting the locale, the request headers are converted to HTTP_CONNECT\xddON from HTTP_CONNECTION, which messes the request and turns the request user into AnonymousUser.
I don't know why this happens but when I removed the locale, it works perfectly.