Переопределение аутентификации Django с промежуточным по
у меня есть сайт Django и форум MyBB, и я хотел бы поделиться аутентификацией между ними. Мой веб-сайт был доской объявлений; затем я построил несколько других разделов в Django, и оба MyBB и Django работают в одном домене. Я создал систему, где при регистрации (на форуме) каждый пользователь получает двух пользователей: пользователя Django и пользователя MyBB. Пользователи используют форум для входа в систему, поэтому мне нужно, чтобы Django прочитал cookies MyBB и установил соответствующую учетную запись Django в качестве зарегистрированного пользователя.
могу ли я сделать это с промежуточным программным обеспечением? Это промежуточное ПО будет читать файлы cookie MyBB (которые содержат идентификатор пользователя MyBB) и установить request.user
соответствующему Пользователю Django. Я новичок в Django, и я не уверен, что установка request.user
(или вызов authenticate
) в промежуточное ПО-это хорошая идея (или если есть лучшие способы сделать это).
4 ответов
Я думаю, что правильным будет сочетание middleware и A Django аутентификации бэкэнд.
ваше промежуточное ПО вызовет серверную authenticate()
возможно, с идентификатором пользователя в качестве ключевого слова. Вы бэкэнд аутентификации в свою очередь вызовете соответствующий authenticate()
метод и возврат объекта user.
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)
Я также рекомендую пройти через это https://docs.djangoproject.com/en/1.2/topics/auth/
Если user_id, хранящийся в вашем файле cookie MyBB, представляет того же пользователя в базе данных Django, вы можете получить объект пользователя прямо из этого идентификатора, используя бэкэнд Django по умолчанию. Если эти идентификаторы не совпадают, вам нужен пользовательский бэкэнд для получения объекта пользователя Django. Чтобы получить идентификатор пользователя из файла cookie MyBB и обновить пользователя на его основе, необходимо иметь настраиваемое промежуточное по аутентификации.
промежуточное
основная идея состоит в том, чтобы получить объект пользователя (на основе ваша логика аутентификации) и назначьте ее request.пользователь. Вот один пример (не проверял).
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)
имейте в виду, что это вызывается для каждого запроса, отправленного на ваш сайт Django. Для производительности вы можете кэшировать пользователя и / или выполнять трюк с ленивым объектом, пример.
бэкэнд
Если вам нужно написать свою собственную логику для извлечения объекта пользователя и аутентификации пользователя, вы можете сделать следующий.
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
вам нужно добавить свой пользовательский сервер и промежуточное ПО в файл настроек сайта.
попробуйте справиться с request.session
. request
объект является первым аргументом в представлении. Подробнее о сессии здесь:https://docs.djangoproject.com/en/dev/topics/http/sessions/
вы можете определенно сделать это с middleware: больше информации о middleware здесь:https://docs.djangoproject.com/en/dev/topics/http/middleware/
Я считаю, что лучше использовать process_view
вместо process_request
as process view имеет следующую информацию:
- запрос
- вызываемая функция
- переданных аргументов
process_view(request, view_func, view_args, view_kwargs):
if not request.user.is_authenticated():
return HttpResponseRedirect(settings.LOGIN_URL)
return None
это делает его более гибким, поскольку у нас есть функция information(view_func)
как хорошо.
Поэтому мы можем ограничить это некоторыми функциями также с помощью:
view_func.__name_
что дает имя функции.