Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple Django apps, shared authentication

Two answers to this question, depending on whether sharing is across different sites or different subdomains Second answer: Multiple Django apps, shared authentication

A user goes to site1.com and logs in. Now, if he goes to site2.com, then he should already be logged in (authenticated) at that site.

site1.com and site2.com are handled by different Django apps on the same sever.

I get that the sites can share the database containing the authentication tables. What I don't get is how the session data is handled. After logging in to site1, the user goes to site2. Here he always has request.user = "AnonymousUser: AnonymousUser" instead of a user_id.

I have set it up as here: https://docs.djangoproject.com/en/dev/topics/db/multi-db/ :

site1's settings has a single database that contains the auth models as well as some other data tables. site2's settings has 2 databases. One with its own data tables and also the one used by user1. I essentially copied class AuthRouter and set up the database router.

Is it not possible what I am trying to do? I don't actually understand how the two sites can share session data. Do I need something special outside of Django? Or should this work? I can include my code here, but don't want to confuse the issue if my basic thinking about this is wrong.

EDIT: here is my setup. I am trying this on localhost.

Site1 is running on localhost:8080

site2 is running on localhost:8000

SITE2 APP:

db_router.py:

class AuthRouter(object):
    def db_for_read(self, model, **hints):
        if model._meta.app_label == 'auth':
            return 'the_ui'
        return None
    # same for write

    def allow_syncdb(self, db, model):
        if db == 'the_ui':
            return model._meta.app_label == 'auth'
        elif model._meta.app_label == 'auth':
            return False
        return None

class OtherRouter(object):
    def db_for_read(self, model, **hints):
        return "default"
    # same for write, relation, syncdb

settings.py:

DATABASE_ROUTERS = ['site2_app.db_router.AuthRouter', 'site2_app.db_router.OtherRouter']
SESSION_COOKIE_DOMAIN = 'http://localhost:8080'
SESSION_ENGINE = "django.contrib.sessions.backends.signed_cookies"

DATABASES = {
    'default': {
        # ...
    },
    'the_ui': {
        # ...
    }
}

SITE 1 APP:

# no router
# only single database, same as the "the_ui" used in site2
SESSION_ENGINE = "django.contrib.sessions.backends.signed_cookies"
like image 495
user984003 Avatar asked Aug 14 '13 11:08

user984003


Video Answer


1 Answers

The marked answer is correct based on the initial question of using different sites.

Here is the answer for different subdomains, eg www.site.com and shop.site.com

Use the shared database authentication as described in the question. And then, in both settings.py:

SESSION_ENGINE = "django.contrib.sessions.backends.signed_cookies"
SESSION_COOKIE_DOMAIN = '.site.com' #notice the period
SESSION_COOKIE_NAME = 'my_cookie'
SECRET_KEY = "" the same in both settings.py

There might be some issue about what happens if you have other subdomains that should NOT share this information. Or, maybe not, if you give their cookies different names??

Not sure if this can work on localhost.

like image 60
user984003 Avatar answered Sep 22 '22 23:09

user984003