Как мне проверить, что пользователь уже прошел аутентификацию от deliciouspie?

Когда пользователь аутентифицируется в Django, как я могу проверить это из deliciouspie?

Как только пользователь входит в систему, представление включает в себя некоторый JS, который извлекает данные из API, поддерживаемого deliciouspie.

У меня настроена базовая аутентификация/авторизация django на моих ресурсах, поэтому в браузере появляется окно HTTP-аутентификации. Есть ли способ избежать этого?

Моя идея до сих пор состоит в том, чтобы расширить BasicAuthentication, чтобы он сначала проверял данные сеанса, а когда не находил их, возвращался к http auth? Вызовы AFAIK AJAX включают файлы cookie сеанса, так что теоретически это должно работать? Кто-нибудь делал что-то подобное?


person rytis    schedule 09.09.2011    source источник


Ответы (4)


У меня есть это решение до сих пор:

class MyBasicAuthentication(BasicAuthentication):
    def __init__(self, *args, **kwargs):
        super(MyBasicAuthentication, self).__init__(*args, **kwargs)

    def is_authenticated(self, request, **kwargs):
        from django.contrib.sessions.models import Session
        if 'sessionid' in request.COOKIES:
            s = Session.objects.get(pk=request.COOKIES['sessionid'])
            if '_auth_user_id' in s.get_decoded():
                u = User.objects.get(id=s.get_decoded()['_auth_user_id'])
                request.user = u
                return True
        return super(MyBasicAuthentication, self).is_authenticated(request, **kwargs)

который, кажется, делает то, что я хочу. Если пользователь вошел в систему, то сессия содержит _auth_user_id, если нет, то ключ отсутствует.

Кто-нибудь может подумать о каких-либо проблемах, которые может вызвать этот подход?

person rytis    schedule 09.09.2011

Вы можете проверить этот билет на GitHub deliciouspie:

https://github.com/toastdriven/django-tastypie/issues/197

Автор предлагает очень чистый подход к аутентификации вызова как с помощью методов сеанса, так и методов ключа API.

Там идет фрагмент:

class ApiKeyPlusWebAuthentication(ApiKeyAuthentication):
def is_authenticated(self, request, **kwargs):
    if request.user.is_authenticated():
        return True

    return super(ApiKeyPlusWebAuthentication, self).is_authenticated(request, **kwargs)

def get_identifier(self, request):
    if request.user.is_authenticated():
        return request.user.username
    else:
        return super(ApiKeyPlusWebAuthentication, self).get_identifier(request)
person ulysses    schedule 29.11.2011

Как только пользователь войдет в систему через ваш API, у вас появится пользовательский сеанс Django. Если вы хотите проверить, вошел ли пользователь в систему (например, при обновлении страницы). Ты можешь сделать:

from tastypie.resources import Resource

class LoggedInResource(Resource):
    class Meta:
        pass

    def get_list(self, request, **kwargs):

        from django.http import HttpResponse

        if request.user.is_authenticated():
            return HttpResponse(status=200)
        else:
            return HttpResponse(status=401)

Проверка клиента:

$.ajax({
    type: "GET",
    url: '/api/loggedin/',
    success: function(data) {
        // logged in
    },
    error: function() {
        // not logged in
    }
});
person dan-klasson    schedule 11.03.2013

Пулегиум

Почему бы не так просто, как следующее:

class CommAuthentication(BasicAuthentication):
    def __init__(self, *args, **kwargs):
        super(CommAuthentication, self).__init__(*args, **kwargs)

    def is_authenticated(self, request, **kwargs):
        return request.user.is_authenticated()

Я только начинаю изучать вкусный пирог. приведенный выше код, похоже, работает для меня. Любое преимущество вашего решения?

person John Wang    schedule 17.12.2011
comment
Я думаю, что это будет работать только в том случае, если запрос уже аутентифицирован и установлен файл cookie сеанса. Если вы отправляете запрос с установленным заголовком HTTP Basic Auth, это не удастся, потому что нет сеанса, и вы не вызываете метод суперкласса is_authenticated, который должен обрабатывать эту ситуацию. - person rytis; 18.12.2011
comment
Спасибо, Пулегиум. Я думаю, что это будет работать только в том случае, если запрос уже аутентифицирован, разве не ожидается, что он будет работать таким образом для программного доступа к API? Какова наилучшая практика в отношении аутентификации? В настоящее время у меня есть отдельный API входа в систему, который аутентифицирует пользователя. Только пользователь, успешно прошедший API-интерфейс входа, может использовать другой API-интерфейс Restful. Не уверен, что эта практика в порядке. - person John Wang; 19.12.2011
comment
Кстати, в моем API входа в систему я инициирую файл cookie сеанса - person John Wang; 19.12.2011
comment
Мое понимание RESTful API заключается в том, что не должно поддерживаться никакого состояния (или сеанса). Другими словами, информации, которую вы предоставляете вместе с запросом, должно быть достаточно для его обработки. Это означает, что вам придется отправлять информацию для входа в систему с каждым запросом (в виде базовой аутентификации HTTP или ключа API). - person rytis; 19.12.2011