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 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.