Django, request.user всегда анонимный пользователь - PullRequest
9 голосов
/ 21 марта 2011

Я использую пользовательский сервер аутентификации для Django (который запускается с couchdb).У меня есть пользовательская модель пользователя.

В рамках входа в систему я делаю request.user = user и сохраняю идентификатор пользователя в сеансе.Однако при последующих запросах я не могу получить request.user.Это всегда AnonymousUser.Однако я могу получить идентификатор пользователя из сеанса и подтвердить, что файл cookie сеанса установлен правильно.

Чего мне не хватает?

Я не хочу использовать реляционную базу данных, так как яхочу сохранить все мои пользовательские данные в couchdb.

Редактировать : Я написал класс, который не наследуется от пользователя Django auth.Однако он имеет имя пользователя и атрибуты электронной почты.По этой причине мой бэкэнд не возвращает класс, производный от auth User.

Ответы [ 6 ]

11 голосов
/ 21 марта 2011

request.user устанавливается django.contrib.auth.middleware.AuthenticationMiddleware.

Проверкой django/contrib/auth/middleware.py:

class LazyUser(object):
    def __get__(self, request, obj_type=None):
        if not hasattr(request, '_cached_user'):
            from django.contrib.auth import get_user
            request._cached_user = get_user(request)
        return request._cached_user

class AuthenticationMiddleware(object):
    def process_request(self, request):
        request.__class__.user = LazyUser()
        return None

Затем посмотрите на функцию get_user в django/contrib/auth/__init__.py:

def get_user(request):
    from django.contrib.auth.models import AnonymousUser
    try:
        user_id = request.session[SESSION_KEY]
        backend_path = request.session[BACKEND_SESSION_KEY]
        backend = load_backend(backend_path)
        user = backend.get_user(user_id) or AnonymousUser()
    except KeyError:
        user = AnonymousUser()
    return user

Ваш бэкэнд должен будет реализовать функцию get_user.

4 голосов
/ 23 марта 2015

У меня тоже есть пользовательский бэкэнд аутентификации, и я всегда получаю AnonymousUser после успешной аутентификации и входа в систему. У меня был метод get_user в моем бэкэнде. Чего мне не хватало, так это того, что get_user должен получить пользователя только по pk, а не по электронной почте или каковы ваши учетные данные в authenticate:

class AccountAuthBackend(object):

@staticmethod
def authenticate(email=None, password=None):
    try:
        user = User.objects.get(email=email)
        if user.check_password(password):
            return user
    except User.DoesNotExist:
        return None

@staticmethod
def get_user(id_):
    try:
        return User.objects.get(pk=id_) # <-- tried to get by email here
    except User.DoesNotExist:
        return None

В документах пропустить эту строку легко:

Метод get_user принимает user_id - это может быть имя пользователя, идентификатор базы данных или что-то еще, но должен быть первичным ключом вашего пользователя object - и возвращает объект User.

Так получилось, что email не является первичным ключом в моей схеме. Надеюсь, это сэкономит кому-то время.

4 голосов
/ 21 марта 2011

Вы говорите, что написали пользовательский бэкэнд аутентификации, но на самом деле то, что вы, кажется, написали, является полным пользовательским приложением аутентификации, которое не взаимодействует с contrib.auth.

Джанго.чтобы использовать нереляционную базу данных для ваших данных аутентификации, все, что вам нужно сделать, это создать класс, который предоставляет два метода: get_user(user_id) и authenticate(**credentials).См. документацию .Как только вы аутентифицируете пользователя, вы просто вызываете обычные методы входа в Django.Не должно быть никаких причин вручную устанавливать request.user или помещать что-либо в сеанс.

Обновление после редактирования Это не имеет к этому никакого отношения.Не требуется, чтобы пользовательский класс был производным от auth.models.User.Вам все еще нужно определить метод get_user, который будет возвращать экземпляр вашего пользовательского класса.

2 голосов
/ 21 марта 2011

Пожалуйста, уточните. Если вы используете пользовательскую модель пользователя (которая отличается от пользовательской модели PROFILE), то вы в основном сами по себе, и платформа django.contrib.auth не может помочь вам с аутентификацией. Если вы пишете свою собственную систему аутентификации и не используете django.contrib.auth, вам необходимо отключить это, так как это, похоже, мешает вашей системе.

0 голосов
/ 12 ноября 2018

После отправки токена с помощью заголовка авторизации токен будет получен в диспетчерской функции, как показано ниже: '' '

def dispatch(self, request, *args, **kwargs):

    self.args = args
    self.kwargs = kwargs
    request = self.initialize_request(request, *args, **kwargs)
    self.request = request
    self.headers = self.default_response_headers  # deprecate?

    try:
        self.initial(request, *args, **kwargs)

        # Get the appropriate handler method
        if request.method.lower() in self.http_method_names:
            handler = getattr(self, request.method.lower(),
                              self.http_method_not_allowed)
        else:
            handler = self.http_method_not_allowed

        response = handler(request, *args, **kwargs)

    except Exception as exc:
        response = self.handle_exception(exc)

    self.response = self.finalize_response(request, response, *args, **kwargs)
    return self.response

Таким образом, вы используете HasRoleMixin django_role_permission, метод отправки этого миксина будет скрывать отправку представления. Я думаю, что решение состоит в том, чтобы переопределить сочетание ролей-разрешений

0 голосов
/ 29 сентября 2018

У меня была похожая проблема, когда я использовал пользовательский бэкэнд аутентификации.Я использовал поле, отличное от первичного ключа в методе get_user .Это решается непосредственно после использования первичного ключа, который должен быть числом (не str)

def get_user(self, user_id):
    try:
        return User.objects.get(pk=user_id) # <-- must be primary key and number
    except User.DoesNotExist:
        return None
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...