I have a Django website and a MyBB forum, and I'd like to share authentication between them. My website used to be a message board; then I built a few other sections in Django, and both MyBB and Django run on the same domain. I've set up a system where upon registration (on the forum) every user gets two users: a Django user and a MyBB user. Users use the forum to log in, so I need Django to read MyBB's cookies and set the corresponding Django account as the logged user.
Can I do that with a middleware? This middleware would read MyBB's cookies (which contain the id of the MyBB user) and set request.user
to the corresponding Django user. I'm new to Django, and I'm not sure if setting request.user
(or calling authenticate
) in a middleware is a good idea (or if there are better ways to do it).
If request.user is not authenticated, then this middleware attempts to authenticate the username passed in the ``REMOTE_USER`` request header. If authentication is successful, the user is automatically logged in to persist the user in the session. The header used is configurable and defaults to ``REMOTE_USER``.
Activating middleware To activate a middleware component, add it to the MIDDLEWARE list in your Django settings. A Django installation doesn't require any middleware — MIDDLEWARE can be empty, if you'd like — but it's strongly suggested that you at least use CommonMiddleware .
The Django authentication system handles both authentication and authorization. Briefly, authentication verifies a user is who they claim to be, and authorization determines what an authenticated user is allowed to do. Here the term authentication is used to refer to both tasks.
If the user_id stored in your MyBB cookie represents the same user in Django database then you can get the user object straight from that id using default Django backend. If those IDs don't match you need custom backend to get the Django user object. To get the user ID from MyBB cookie and update the user based on it, you need to have a custom authentication middleware.
Middleware
The main idea is to fetch the user object (based on your authentication logic) and assign it to request.user. Here is one example (not tested).
from django.contrib import auth
class MyBBMiddleware:
def process_request(self, request):
user_cookie_name = "session_key"
if user_cookie_name not in request.COOKIES:
# log user out if you want
return
id = request.COOKIES.get(user_cookie_name)
# this will find the right backend
user = auth.authenticate(id)
request.user = user
# if you want to persist this user with Django cookie do the following
#auth.login(request, user)
Keep in mind that this is called for every request sent to your Django site. For performance you could cache the user and/or do a lazy object trick, EXAMPLE.
Backend
If you need to write your own logic for fetching user object and authenticating a user, you could do the following.
class MyBBCookieBackend(object):
def authenticate(self, user_id):
return self.get_user(user_id)
def get_user(self, user_id):
# if user_id is not the same in Django and MyBB tables,
# you need some logic to relate them and fetch Django user
try:
#TODO your custom logic
user = User.objects.get(id=user_id)
return user
except User.DoesNotExist:
return None
You need to add your custom backend and middleware in the site settings file.
I think the right thing to will be a combination of middleware and a Django authentication backend.
Your middleware will call the backend's authenticate()
with possibly the user id as a keyword argument. You authentication backend in turn will call the corresponding authenticate()
method and return a user object.
class MiddlewareTracker:
def process_request(self, request):
id = request.COOKIES.get('logged_in_id')
authenticate(user_id = id)
return None
class ForumAuthBackend(object):
def authenticate(self, *args, **kwargs):
id = kwargs.get('user_id')
return User.objects.get(id = id)
def get_user(self, user_id):
return User.objects.get(id = user_id)
I will also recommend going through this https://docs.djangoproject.com/en/1.2/topics/auth/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With