Created
July 26, 2013 00:38
-
-
Save dustinfarris/6085132 to your computer and use it in GitHub Desktop.
This is a dated document and may be improved on.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Sharing Django Users and Sessions Across Projects | |
By Dustin Farris on 22 Feb 2012 | |
This document describes how to share users created using Django's auth system with other | |
Django projects. It is not a hack; it simply makes use of the database router and | |
middleware system that Django comes with out of the box. | |
## Introduction | |
There may come a time when you need to share your Django users with another Django | |
project. In my case, I created a subdomain under a new project for handling user-specific | |
tasks, but I wanted the original domain to have access to some data of logged in users, | |
(name, userprofile information, etc...) This document shows how to "reroute" frontend | |
auth and session requests from one Django project to another without breaking the admin | |
for either project. | |
## Prerequisites | |
You must be running Django 1.2 or higher to make use of the new | |
[multiple database feature][]. I'll assume you have all your users in a project running | |
OldWebsite.com, and you would also like to access those same sessions and users from a | |
separate project, NewWebsite.com. Both should have their own databases that are | |
already synced. | |
## Set up database configuration | |
Set up a database configuration in the NewWebsite.com project that points to the database | |
housing the users and sessions for NewWebsite.com: | |
```python | |
DATABASES = { | |
'default': { | |
. | |
. | |
. | |
}, | |
'usersandsessions': { | |
'ENGINE': ..., | |
'NAME': ..., | |
'USER': ..., | |
'PASSWORD': ..., | |
'HOST': ..., | |
'PORT': ..., | |
}, | |
} | |
``` | |
## Set up router and middleware | |
Create a file routers.py in your project directory for NewWebsite.com. The middleware is | |
crucial as it determines whether to actually use the router based on whether the user is | |
accessing an admin page or a regular page. | |
```python | |
""" | |
NewWebsite.com's router | |
Establishes rules to forward user and session db requests | |
to ExampleA.com unless we are accessing the admin. | |
""" | |
import threading | |
# Object to hold request data | |
request_cfg = threading.local() | |
class RouterMiddleware(object): | |
""" | |
Sets a flag if we are accessing Django admin to | |
prevent database rerouting for the auth model. | |
Removes the flag once the request has been processed. | |
""" | |
def process_view(self, request, view_func, args, kwargs): | |
if request.path.startswith('/admin'): | |
request_cfg.admin = True | |
def process_response(self, request, response): | |
if hasattr(request_cfg, 'admin'): | |
del request_cfg.admin | |
class UserSessionRouter(object): | |
""" | |
Redirects database IO for the auth and sessions | |
models to OldWebsite.com. | |
""" | |
def db_for_read(self, model, **hints): | |
if not hasattr(request_cfg, 'admin'): | |
if model._meta.app_label == 'auth': | |
return 'usersandsessions' | |
elif model._meta.app_label == 'accounts': | |
return 'usersandsessions' | |
elif model._meta.app_label == 'sessions': | |
return 'usersandsessions' | |
return None | |
def db_for_write(self, model, **hints): | |
if not hasattr(request_cfg, 'admin'): | |
if model._meta.app_label == 'auth': | |
return 'usersandsessions' | |
elif model._meta.app_label == 'accounts': | |
return 'usersandsessions' | |
elif model._meta.app_label == 'sessions': | |
return 'usersandsessions' | |
return None | |
``` | |
Add the router setting to settings.py: | |
```python | |
DATABASE_ROUTERS = ['project.routers.UserSessionRouter'] | |
``` | |
And add the middleware at the top of your middleware classes: | |
```python | |
MIDDLEWARE_CLASSES = [ | |
'project.routers.RouterMiddleware', | |
..., | |
..., | |
..., | |
] | |
``` | |
## Match the secret keys | |
If you only want to share users then your work is done. If you want to share sessions, | |
however, you must change one or both of your ``SECRET_KEY`` settings to match each other. | |
## Match the session cookie domain | |
Just like the secret keys, the ``SESSION_COOKIE_DOMAIN`` setting from OldWebsite.com and | |
NewWebsite.com must match if you want to share sessions. | |
## Conclusion | |
That's it. Now when a user logs in at OldWebsite.com, you will have access to | |
``request.user`` and ``request.user.get_profile()`` (if you use it) from both sites until | |
the user logs out. Accessing NewWebsite.com/admin however will use NewWebsite.com's own | |
user database. Remember to modify routers.py if you have any special needs. | |
[multiple database feature]: http://docs.djangoproject.com/en/dev/topics/db/multi-db/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment