Jak sprawdzić, czy użytkownik jest zalogowany (jak prawidłowo korzystać z user.is_authenticated)?

250

Patrzę na tę stronę, ale nie mogę pojąć, jak to zrobić, ponieważ nie działa. Muszę sprawdzić, czy bieżący użytkownik witryny jest zalogowany (uwierzytelniony) i próbuję:

request.user.is_authenticated

pomimo upewnienia się, że użytkownik jest zalogowany, zwraca tylko:

>

Jestem w stanie wykonać inne żądania (z pierwszej sekcji powyższego adresu URL), takie jak:

request.user.is_active

która zwraca pomyślną odpowiedź.

Stóg
źródło
1
is_authenticated (zarówno wewnątrz, jak i na zewnątrz szablonów) zawsze zwraca True - niezależnie od tego, czy użytkownik jest faktycznie zalogowany, czy nie. Aby naprawdę sprawdzić, czy użytkownik jest zalogowany, jedynym rozwiązaniem wydaje się porównanie ostatniej / ostatniej daty / godziny z limitem czasu
Tony Suffolk 66

Odpowiedzi:

509

Aktualizacja dla Django 1.10+ : is_authenticatedjest teraz atrybutem w Django 1.10. Metoda nadal istnieje dla kompatybilności wstecznej, ale zostanie usunięta w Django 2.0.

Dla Django 1.9 i starszych :

is_authenticatedjest funkcją. Powinieneś to tak nazwać

if request.user.is_authenticated():
    # do something if the user is authenticated

Jak zauważył Peter Rowell, może Cię to potknąć, że w domyślnym języku szablonów Django nie używasz nawiasów do wywoływania funkcji. Być może widziałeś coś takiego w kodzie szablonu:

{% if user.is_authenticated %}

Jednak w kodzie Python jest to rzeczywiście metoda w Userklasie.

Brian Neal
źródło
och ok .. dzięki za informację, która ma sens, to dlaczego nie działała, chyba że coś przeoczyłem, naprawdę nie jest to jasne w dokumentacji django
Rick
2
@ Rick: Zaczynam się od ciebie różnić. is_authenticated () to drugi element wymieniony w sekcji metod modeli klas. Co może być mylące jest to, że język szablon ma nie korzystać z tylną () 's, więc można zobaczyć coś takiego: {% if user.is_authenticated%}. Jeśli wstawisz (), pojawi się błąd. (Zobacz docs.djangoproject.com/en/dev/topics/auth/… i docs.djangoproject.com/en/1.2/topics/templates/#variables )
Peter Rowell,
2
@Peter, no cóż, nie używają () w przykładach, zdaję sobie sprawę, że jestem pewien, że wyjaśnili gdzieś, że jest to metoda i jak to zrobić poprawnie, po prostu fajnie, gdy API używa w niej prawdziwej składni może zostać szybko przyjęty przez kogoś nowego w projekcie, takim jak Django, po prostu sikanie ze zwierzęciem Myślę, że mam tendencję do przeglądania rzeczy, ale zdaję sobie sprawę, że powinienem był przyjrzeć się bliżej, dzięki za pomoc
Rick
4
@ Rick: Całkowicie zgadzam się z tobą w sprawie prawdziwej składni. Słyszałem (jak sądzę) kiepskie powody, dla których nie używają „prawdziwego” języka programowania dla systemu szablonów, ale tak właśnie zrobili. Możesz wybrać użycie Jinja2 ( jinja.pocoo.org/2 ), a to zapewni pełne możliwości Pythona, ale ponieważ przeważająca większość aplikacji innych firm korzysta z systemu Django, często trudno jest je zmieszać. Spójrz na ExprTag ( djangosnippets.org/snippets/9 ), aby znaleźć sposób na wyrażenie w szablonach Django. To działa.
Peter Rowell,
3
@ Rick dokumentacja mówi różne rzeczy dla różnych wersji. Wygląda na to, że dla 1.10 nie jest to już metoda
yairchu,
32

Django 1.10+

Użyj atrybutu, a nie metody:

if request.user.is_authenticated: # <-  no parentheses any more!
    # do something if the user is authenticated

Zastosowanie metody o tej samej nazwie jest przestarzałe w Django 2.0 i nie jest już wspomniane w dokumentacji Django.


Zauważ, że dla Django 1.10 i 1.11 wartość tej właściwości to a, CallableBoola nie wartość logiczna, co może powodować dziwne błędy. Na przykład miałem widok, który zwrócił JSON

return HttpResponse(json.dumps({
    "is_authenticated": request.user.is_authenticated()
}), content_type='application/json') 

że po aktualizacji do właściwości request.user.is_authenticatedzgłaszał wyjątek TypeError: Object of type 'CallableBool' is not JSON serializable. Rozwiązaniem było użycie JsonResponse, który mógł poprawnie obsługiwać obiekt CallableBool podczas szeregowania:

return JsonResponse({
    "is_authenticated": request.user.is_authenticated
})
Mark Chackerian
źródło
1
ale is_authentified (zarówno wewnątrz, jak i na zewnątrz szablonów) zawsze zwraca True dla prawdziwego użytkownika (i False dla anonimowego użytkownika) - niezależnie od tego, czy użytkownik jest faktycznie zalogowany, czy nie.
Tony Suffolk 66
W porządku, ponieważ ta metoda jest używana request.user. To, czy użytkownik jest zalogowany, czy nie ma znaczenia tylko w kontekście żądania, na przykład sesji przeglądarki.
Mark Chackerian,
Zakładając, że aplikacja poprawnie wylogowuje użytkowników - widziałem takich, którzy tego nie robią.
Tony Suffolk 66
22

Następujący blok powinien działać:

    {% if user.is_authenticated %}
        <p>Welcome {{ user.username }} !!!</p>       
    {% endif %}
Sopan
źródło
2
ale is_authenticated (zarówno wewnątrz, jak i na zewnątrz szablonów) zawsze zwraca True - niezależnie od tego, czy użytkownik jest faktycznie zalogowany, czy nie.
Tony Suffolk 66
Dokument mówi: Atrybut tylko do odczytu, który zawsze ma wartość Prawda (w przeciwieństwie do AnonymousUser.is_authenticated, który zawsze ma wartość False). Jest to sposób na sprawdzenie, czy użytkownik został uwierzytelniony. Nie oznacza to żadnych uprawnień i nie sprawdza, czy użytkownik jest aktywny lub ma prawidłową sesję. Chociaż zwykle sprawdzasz ten atrybut na request.user, aby dowiedzieć się, czy został on wypełniony przez AuthenticationMiddleware (reprezentujący aktualnie zalogowanego użytkownika), powinieneś wiedzieć, że ten atrybut jest prawdziwy dla każdej instancji użytkownika.
Sopan
Jeśli więc chcesz wyświetlać - nieuwierzytelnionych użytkowników jako „Witamy gościa” i uwierzytelnić użytkowników jako „Witamy .USERNAME”, może działać następujący blok w szablonach: {% if user.is_authenticated%} <p> Witamy {{user.username }} !!! </p> {% else%} <p> Witaj gościu !!! </p> {% endif%}
Sopan
7

Twoim zdaniem:

{% if user.is_authenticated %}
<p>{{ user }}</p>
{% endif %}

W tobie funkcje kontrolera dodaj dekorator:

from django.contrib.auth.decorators import login_required
@login_required
def privateFunction(request):
Cubiczx
źródło
ale is_authenticated (zarówno wewnątrz, jak i na zewnątrz szablonów) zawsze zwraca True - niezależnie od tego, czy użytkownik jest faktycznie zalogowany, czy nie.
Tony Suffolk 66
lepiej dla użytkownika, request.user.is_authenticatedjeśli wiesz, że Twoja aplikacja zawsze wyloguje użytkownika
Tony Suffolk 66
0

Jeśli chcesz sprawdzić uwierzytelnionych użytkowników w swoim szablonie:

{% if user.is_authenticated %}
    <p>Authenticated user</p>
{% else %}
    <!-- Do something which you want to do with unauthenticated user -->
{% endif %}
Suyash Kumar
źródło
-5

W przypadku wersji Django 2.0+ użyj:

    if request.auth:
       # Only for authenticated users.

Aby uzyskać więcej informacji, odwiedź https://www.django-rest-framework.org/api-guide/requests/#auth

request.user.is_authenticated () został usunięty w wersjach Django 2.0+.

Jatin Goyal
źródło
7
request.user.is_authenticatedjest ciągle ważny. Odwołujesz się do dokumentacji django-rest-framework, a nie django
grouchoboy