Uwierzytelnianie Django i Ajax-adresy URL wymagające logowania

Chcę dodać trochę Ajax - niceness do mojej strony kodowanej w Django.

W moim kodzie Django, używam dekoratora @login_required z django.contrib.auth.decorators aby zaznaczyć, który Widok wymaga uwierzytelnienia. Domyślnym zachowaniem, gdy nie uwierzytelniony użytkownik kliknie, jest przekierowanie go na stronę logowania, a następnie przejście do strony docelowej.

To, co widziałem na niektórych stronach, i naprawdę lubiłem, to to, że gdy użytkownik kliknie link prowadzący do miejsca ograniczonego do zalogowanych użytkowników, zamiast zostać przekierowanym do strona logowania, dostaje wyskakujące okno (przez JavaScript) z prośbą o zalogowanie się lub rejestrację. Nie ma części przekierowania, więc nie ma potrzeby, aby użytkownik używał klucza "wstecz", jeśli zdecyduje, że naprawdę nie lubi strony na tyle, aby tracić czas na rejestrację.

Pytanie brzmi: jak można zarządzać zadaniem automatycznego oznaczania niektórych linków jako "ograniczone", aby JavaScript mógł obsługiwać ich onclick Zdarzenie i wyświetlać wyskakujące okienko" Proszę się zalogować"?

Author: Peter Mortensen, 2008-11-23

5 answers

Stoję przed tym samym problemem i, podobnie jak ty, chciałbym, aby prosty dekorator owijał wokół widoku Django ajax, aby obsługiwać uwierzytelnianie w taki sam sposób, w jaki mam inne widoki. Jednym z podejść, które wydaje mi się obiecujące, jest użycie takiego dekoratora w połączeniu z JavaScript, który szuka określonej wartości w odpowiedzi.

Oto pierwszy poprawiony projekt dekoratora:

from functools import wraps

def ajax_login_required(view_func):
    @wraps(view_func)
    def wrapper(request, *args, **kwargs):
        if request.user.is_authenticated():
            return view_func(request, *args, **kwargs)
        json = simplejson.dumps({ 'not_authenticated': True })
        return HttpResponse(json, mimetype='application/json')
    return wrapper

Oto widok:

@ajax_login_required
def ajax_update_module(request, module_slug, action):
    # Etc ...
    return HttpResponse(json, mimetype='application/json')

A oto JavaScript (jQuery):

$.post('/restricted-url/', data, function(json) {
    if (json.not_authenticated) {
        alert('Not authorized.');  // Or something in a message DIV
        return;
    }
    // Etc ...
});

EDIT : próbowałem użyć functools.wraps, zgodnie z sugestią. Nie używałem tego dekoratora w kodzie roboczym, więc uważaj na ewentualne błędy.

 54
Author: Eric Walker,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-31 16:06:32

Brzmi jak możliwość szablonu strony.

  1. Możesz przekazać LINK_VIA (lub coś), które podajesz jako onClick="return popup(this, 'arg')" lub None. Każdy link będzie <A HREF="link" {{LINK_VIA}}>some text</a>.

    • dla sesji anonimowych, LINK_VIA ma wartość.
    • dla zalogowanych sesji, LINK_VIA jest brak
  2. Możesz użyć {% if %} Oświadczenia wokół swoich <A HREF=...> tagów. To brzmi strasznie.

  3. Możesz napisać własny niestandardowy znacznik za pomocą for {% link_via %}. I ' m not familiar enough dzięki temu możesz podać link i tekst jako ciągi znaków, a Twój tag może wygenerować jeden z dwóch rodzajów linków.

 5
Author: S.Lott,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-23 21:53:30

Zgadzam się z S. Lott

Sprawdź w szablonie, jeśli użytkownik jest zalogowany, po prostu umieść link jak zwykle, jeśli nie, umieść coś w stylu

<a href="{{link}}" onclick="return login_popup()"> 

Gdzie login_popup zwróci false, jeśli użytkownik powie anuluj.

Prawdopodobnie można to zrobić znacznie łatwiej w Jinja2 poprzez jego makra .

Jeśli szablon nie wie, które adresy URL wymagają zalogowania użytkownika, prawdopodobnie musisz ponownie rozważyć swój projekt.

Jeśli musisz, myślę, że możesz zrobić to samo, co Django URL dispatcher, aby odkryć funkcję widoku.
zobacz: django.core.urlresolvers

Po użyciu funkcji view możesz sprawdzić, czy jest ona ozdobiona znakiem @ login_required.

Prawdopodobnie byłoby to zrobione w niestandardowym znaczniku.
Jeśli używasz Jinja2, nie potrzebujesz tagu, po prostu zaimplementuj funkcję i wystawiaj ją na działanie środowiska, jest to proste, ale musisz trochę poczytać w API Jinja2)

 5
Author: hasen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:46:40

Oto proponowana wersja dekoratora z okładem._/ align = "left" / __ Nazwa _ _

from functools import wraps

def ajax_login_required(function):
    def wrap(request, *args, **kwargs):
        if request.user.is_authenticated():
            return function(request, *args, **kwargs)
        json = simplejson.dumps({ 'not_authenticated': True })
        return HttpResponse(json, mimetype='application/json')  
    wrap.__doc__ = function.__doc__
    wrap.__name__ = function.__name__
    return wrap
 1
Author: Mohamed Ould El Kory,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-21 10:44:48

Zbudowany z Rozwiązania Erica Walkera , ale dla Django 2.0

# Standard Imports
import functools
import django.http

def ajax_login_required(view_func):
    @functools.wraps(view_func)
    def wrapper(request, *args, **kwargs):
        if request.user.is_authenticated:
            return view_func(request, *args, **kwargs)

        return django.http.JsonResponse('Unauthorized', status=401, safe=False)

    return wrapper
 0
Author: Warren Spencer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-01 16:07:17