Django Request Session on anonymous users - django

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?

Related

Session is not storing variables - 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.")

Django2: How to share 'request.user' with localhost:8000 and subdomain analysis.localhost:8000?

i am building a blog using Django, and i have implemented an analysis tool that allows me to plot details about my visitors (country_origin, device, browser, ...).
analysis.localhost:8000 is a subdomain of localhost , defined as a class based view with a custom Mixin SuperuserAccessRequired, that returns a 401 Unauthorized if the user is not staff (i am using django-hosts to handle subdomains & this is my first time working with subdomains.).
My issue:
if i am logged in on localhost:8000 and naviguate to analysis.localhost:8000 i get the 401 response.
You are seeing this as: AnonymousUser # generated by print(You are seeing this as: ', request.user) from SuperuserAccessRequired
Unauthorized: /
[25/Sep/2019 13:14:03] "GET / HTTP/1.1" 401 89
my humble assumption says that localhost:8000 and x.localhost:8000 are not sharing certain variables.
How can i fix this issue, i have read django-hosts documentation like 5 times already and i can't seem to find what i am missing
my code :
project/root/settings.py
...
ALLOWED_HOSTS = ['localhost']
ALLOWED_HOSTS += ['analysis.localhost', 'blog.localhost']
SITE_ID = 1
INSTALLED_APPS += [
# Django Apps
'blog',
'analysis',
]
INSTALLED_APPS += [
# Django Dependencies
'sass_processor',
'django_hosts',
]
MIDDLEWARE = [
'django_hosts.middleware.HostsRequestMiddleware',
'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',
'analysis.middleware.TrackVisitorMiddleware',
'django_hosts.middleware.HostsResponseMiddleware',
]
ROOT_URLCONF = 'root.urls'
ROOT_HOSTCONF = 'root.hosts'
BLOG_URLCONF = 'blog.urls'
ANALYSIS_URLCONF = 'analysis.urls'
DEFAULT_HOST = 'www'
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
},
'analysis': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'analysis_db.sqlite3'),
}
}
...
project/root/hosts.py
host_patterns = patterns('',
host(r'localhost:8000', settings.ROOT_URLCONF, name='www'),
host(r'analysis.localhost:8000', settings.ANALYSIS_URLCONF, name='analysis'),
host(r'blog.localhost:8000', settings.BLOG_URLCONF, name='blog'),
)
Custom Mixin:
class SuperuserAccessRequired(AccessMixin):
"""Verify that the current user is staff."""
def dispatch(self, request, *args, **kwargs):
print('You are seeing this as: ', request.user)
if not request.user.is_staff:
return HttpResponse(status=401, content='You are not authorized to view this page.')
return super().dispatch(request, *args, **kwargs)
UPDATE
If i remove the port number from analysis.localhost i get redirected to the Apache default page ... weird. (just dismiss this update i forgot about /etc/hosts, man i am losing it)
UPDATE 2
Digging deeper into the matter it looks like i have to rewrite my SessionMiddleware.
Any help/guidance would be appreciated.
You need to set SESSION_COOKIE_DOMAIN for share cookie between subdomains.
SESSION_COOKIE_DOMAIN = '.localhost'
SESSION_COOKIE_NAME = 'sharesession'
See more info SESSION_COOKIE_DOMAIN

Do I need custom backend for django If my User model is custom?

A quick question.I had implemented a custom user model with its manager .Registration is working great ,but whenever user is logging in it shows AnonymousUser. Does this mean that I need to implement cutsom backend ot what ?? if yes could anyone give me an example of custom backend for custom user model.
Kind regards
EDIT:here is my settings file
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'custom_user' ,
]
ROOT_URLCONF = 'jam.urls'
WSGI_APPLICATION = 'jam.wsgi.application'
AUTHENTICATION_BACKENDS = ('custom_user.backends.ClientAuthBackend', 'django.contrib.auth.backends.ModelBackend')
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME':'test3',
'USER':'root',
'PASSWORD':'',
}
}
AUTH_USER_MODEL='custom_user.EmailUser'
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
STATIC_URL = '/static/'
and this is backends.py
class ClientAuthBackend(object):
def authenticate(self, username=None, password=None):
try:
user = EmailUser.objects.get(email=username)
if EmailUser.check_password(password, user.password):
return user
except EmailUser.DoesNotExist:
return None
def get_user(self, user_id):
try:
return EmailUser.objects.get(pk=user_id)
except EmailUser.DoesNotExist:
return None
a quick answer - no you dont need custom backend. If you want to replace the user model, you need to set AUTH_USER_MODEL = 'yourapp.YourUserModel'
custom backend is needed if you want to change something in authentication (can also be other reasons) cycle. e.g. authenticate against email instead of username etc ...

How to achieve LDAP authentication in Django, How to access User object in View?

I want to build a site using Django wherein to enter it, the users have to authenticate themselves through LDAP server.
I have read the python-ldap configuration and configured settings.py accordingly. I'm able to authenticate a user from local database, but when I try to do it through LDAP, it doesn't work.
import os
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
TEMPLATE_DIRS = [os.path.join(BASE_DIR,'templates')]
import ldap
from django_auth_ldap.config import LDAPSearch, GroupOfNamesType
# Baseline configuration.
AUTH_LDAP_SERVER_URI = "ldap://10.1.10.10"
AUTH_LDAP_CONNECTION_OPTIONS = {
ldap.OPT_REFERRALS: 0
}
AUTH_LDAP_BIND_DN = "cn=myname,dc=example,dc=com"
AUTH_LDAP_BIND_PASSWORD = "dontevenask"
AUTH_LDAP_USER_SEARCH = LDAPSearch("ou=users,dc=example,dc=com",
ldap.SCOPE_SUBTREE, "(uid=%(user)s)")
#AUTH_LDAP_USER_DN_TEMPLATE = "uid=%(user)s,ou=users,dc=example,dc=com"
AUTH_LDAP_USER_ATTR_MAP = {
"first_name": "givenName",
"last_name": "sn",
"email": "mail"
}
AUTH_LDAP_ALWAYS_UPDATE_USER = True
AUTH_LDAP_FIND_GROUP_PERMS = True
AUTHENTICATION_BACKENDS = (
'django_auth_ldap.backend.LDAPBackend',
'django.contrib.auth.backends.ModelBackend',
)
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.7/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '^eh5xdkui7vw!^x&l%q44ak6+yglnx5q(tqwd8l+w!sxml7q!&'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
TEMPLATE_DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'my_app',
)
MIDDLEWARE_CLASSES = (
'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',
)
ROOT_URLCONF = 'users.urls'
WSGI_APPLICATION = 'users.wsgi.application'
# Database
# https://docs.djangoproject.com/en/1.7/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'OPTIONS':{
'read_default_file':'/home/user/config.cnf',
},
}
}
# Internationalization
# https://docs.djangoproject.com/en/1.7/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.7/howto/static-files/
STATIC_URL = '/static/'
Here is my views.py file
def loggedin(request):
uid = request.user.username
return render_to_response('loggedin.html',
{'full_name':uid})
And the loggedin.html file
{% block content %}
<h2> Hi {{full_name}} Logged in! </h2>
<p> Click here to logout </p>
{% endblock %}
I did refer to other posts but didn't find the solution.
What am I missing?
There are several issues that might cause the LDAP authentication not to work.
I am assuming you are running linux host. Have you verified that the LDAP settings you have entered works properly? Use command line tool 'ldapsearch' verify that the server works and responses as you might expect.
After you have successfully authenticated with ldapsearch and the authentication is still not working in Django i suggest you put logging on on and paste the logs somewhere.
Without futher info its hard to say what part of your setup is incorrect.
So, here goes the answer!
I changed "(uid=%(user)s)") to "(samaccountname=%(user)s)") which did the trick.
Having the logger helped locate what the problem was - was it even talking to LDAP or just trying to authenticate with the local database.

django-social-auth incorrect authentication service

I was trying to use django-social-auth today, but turned out I got an error everytime I tried to login using it.
I was using the example found in its git master branch, put in my facebook keys, but when I click to login using facebook, the error "Incorrect authentication service" appears.
That also occurs in twitter and orkut logins... does anyone have any idea why that may be happening?
Thanks a lot!
Edit
Yeah, I'm sorry, I forgot to post my code.
settings.py
from os.path import abspath, dirname, basename, join
DEBUG = True
TEMPLATE_DEBUG = DEBUG
ROOT_PATH = abspath(dirname(__file__))
PROJECT_NAME = basename(ROOT_PATH)
ADMINS = (
# ('Your Name', 'your_email#domain.com'),
)
MANAGERS = ADMINS
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': 'test.db',
}
}
TIME_ZONE = 'America/Chicago'
LANGUAGE_CODE = 'en-us'
SITE_ID = 1
USE_I18N = True
USE_L10N = True
MEDIA_ROOT = ''
ADMIN_MEDIA_PREFIX = '/admin-media/'
MEDIA_URL = ''
SECRET_KEY = '****'
TEMPLATE_LOADERS = (
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
)
MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
)
ROOT_URLCONF = 'urls'
TEMPLATE_DIRS = (
join(ROOT_PATH, 'templates')
)
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.admin',
'social_auth',
'app',
)
AUTHENTICATION_BACKENDS = (
'social_auth.backends.twitter.TwitterBackend',
'social_auth.backends.facebook.FacebookBackend',
'social_auth.backends.google.GoogleOAuthBackend',
'social_auth.backends.google.GoogleOAuth2Backend',
'social_auth.backends.google.GoogleBackend',
'social_auth.backends.yahoo.YahooBackend',
'social_auth.backends.contrib.linkedin.LinkedinBackend',
'social_auth.backends.OpenIDBackend',
'social_auth.backends.contrib.livejournal.LiveJournalBackend',
'django.contrib.auth.backends.ModelBackend',
)
try:
from local_settings import *
except:
pass
local_settings.py
TWITTER_CONSUMER_KEY = ''
TWITTER_CONSUMER_SECRET = ''
FACEBOOK_APP_ID = '226521154024720'
FACEBOOK_API_SECRET = '9955be3b6e211b51921cb4b8eb08e69e'
LINKEDIN_CONSUMER_KEY = ''
LINKEDIN_CONSUMER_SECRET = ''
ORKUT_CONSUMER_KEY = ''
ORKUT_CONSUMER_SECRET = ''
GOOGLE_OAUTH2_CLIENT_KEY = ''
GOOGLE_OAUTH2_CLIENT_SECRET = ''
SOCIAL_AUTH_CREATE_USERS = True
SOCIAL_AUTH_FORCE_RANDOM_USERNAME = False
SOCIAL_AUTH_DEFAULT_USERNAME = 'socialauth_user'
SOCIAL_AUTH_COMPLETE_URL_NAME = 'complete'
LOGIN_ERROR_URL = '/login/error/'
#SOCIAL_AUTH_USER_MODEL = 'app.CustomUser'
SOCIAL_AUTH_ERROR_KEY = 'socialauth_error'
The rest of the codes are exactly the same in example in github.com/omab/django-social-auth
if you need any other code, just tell me.
Thanks a lot!
In my case the problem was that I had FACEBOOK_APP_SECRET instead of FACEBOOK_API_SECRET. It was due to the fact that I migrated from django-facebook to django-social-auth.
It may be you don't have the FACEBOOK_APP_ID or FACEBOOK_API_SECRET set.
Well, without seeing your configuration this will simply be a shot in the dark. But the django-social-auth code has this:
def complete_process(request, backend):
"""Authentication complete process"""
backend = get_backend(backend, request, request.path)
if not backend:
return HttpResponseServerError('Incorrect authentication service')
...
So, offhand, I would guess that you don't have the right backend configured or, at the very least, Django can't find it. Make sure you have the appropriate backend configured in AUTHENTICATION_BACKENDS and that you've obtained the required OAuth keys from the service you want to use.
Keep in mind, too, that this error occurs in the django-social-auth code in a few places, but always when the specified backend can't be retrieved.