Come verificare se un utente ha effettuato l'accesso (come utilizzare correttamente user.is_authenticated)?


250

Sto guardando questo sito Web, ma non riesco proprio a capire come farlo perché non funziona. Devo verificare se l'utente del sito corrente ha effettuato l'accesso (autenticato) e sto provando:

request.user.is_authenticated

nonostante sia sicuro che l'utente abbia effettuato l'accesso, restituisce solo:

>

Sono in grado di fare altre richieste (dalla prima sezione dell'url sopra), come:

request.user.is_active

che restituisce una risposta positiva.


1
is_authenticated (modelli sia interni che esterni) restituisce sempre True, indipendentemente dal fatto che l'utente abbia effettivamente effettuato l'accesso o meno. Per identificare con certezza se un utente ha effettuato l'accesso, l'unica soluzione sembra essere quella di confrontare la data / ora dell'ultimo_successo con il timeout
Tony Suffolk, 66

Risposte:


509

Aggiornamento per Django 1.10+ : is_authenticatedora è un attributo in Django 1.10. Il metodo esiste ancora per la compatibilità con le versioni precedenti, ma verrà rimosso in Django 2.0.

Per Django 1.9 e precedenti :

is_authenticatedè una funzione. Dovresti chiamarlo come

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

Come ha sottolineato Peter Rowell, ciò che potrebbe farti inciampare è che, nel linguaggio predefinito del modello Django, non devi virare sulla parentesi per chiamare le funzioni. Quindi potresti aver visto qualcosa del genere nel codice modello:

{% if user.is_authenticated %}

Tuttavia, nel codice Python, è davvero un metodo nella Userclasse.


oh ok .. grazie per le informazioni, ha senso quindi perché non funzionava, a meno che non mi mancasse qualcosa, non è davvero chiaro su questo nella documentazione di django
Rick

2
@Rick: mi permetto di dissentire da te. is_authenticated () è il secondo elemento elencato nella sezione metodi dei modelli di classe.User. Ciò che può confondere è che il linguaggio dei template non non usa la finale () 's, così si potrebbe vedere qualcosa di simile {% se% user.is_authenticated}. Riceverai un errore se inserisci (). (Vedi docs.djangoproject.com/en/dev/topics/auth/… e docs.djangoproject.com/en/1.2/topics/templates/#variables )
Peter Rowell,

2
@Peter, beh non usano () negli esempi, mi rendo conto che sono sicuro che hanno spiegato da qualche parte che è un metodo e come farlo correttamente, è bello quando un'API usa la sintassi della vita reale in esso in modo che può essere rapidamente accolto da qualcuno che non conosce un progetto come Django, solo un animale domestico che immagino mentre tendo a sfogliare le cose ma mi rendo conto che avrei dovuto guardare più da vicino, grazie per l'aiuto
Rick

4
@Rick: sono completamente d'accordo con te sulla sintassi della vita reale. Ho sentito le ragioni (quelle che considero) povere che hanno per non usare un "vero" linguaggio di programmazione per il sistema di template, ma è quello che hanno fatto. Puoi scegliere di usare Jinja2 ( jinja.pocoo.org/2 ) e ti offrirà funzionalità Python complete, ma poiché la stragrande maggioranza delle app di terze parti utilizza il sistema Django, è spesso difficile mescolarle. Guarda ExprTag ( djangosnippets.org/snippets/9 ) per un modo per ottenere espressioni all'interno dei template di Django. Funziona.
Peter Rowell,

3
@Rick la documentazione dice cose diverse per versione diversa. Sembra che per 1.10 non sia più un metodo
yairchu il

32

Django 1.10+

Usa un attributo, non un metodo:

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

L'uso del metodo con lo stesso nome è obsoleto in Django 2.0 e non è più menzionato nella documentazione di Django.


Si noti che per Django 1.10 e 1.11, il valore della proprietà è un CallableBoole non un valore booleano, che può causare strani bug. Ad esempio, avevo una vista che restituiva JSON

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

che dopo l'aggiornamento alla proprietà request.user.is_authenticatedgenerava l'eccezione TypeError: Object of type 'CallableBool' is not JSON serializable. La soluzione era utilizzare JsonResponse, che poteva gestire correttamente l'oggetto CallableBool durante la serializzazione:

return JsonResponse({
    "is_authenticated": request.user.is_authenticated
})

1
ma is_authenticated (modelli sia interni che esterni) restituisce sempre True per un utente reale (e False per un utente anonimo), indipendentemente dal fatto che l'utente abbia effettivamente effettuato l'accesso o meno.
Tony Suffolk, 66

Va bene perché questo metodo è utilizzato su request.user. Se un utente ha effettuato l'accesso o non conta solo nel contesto della richiesta, ad esempio la sessione del browser.
Mark Chackerian,

Supponendo che l'applicazione disconnetta correttamente gli utenti, ne ho visti alcuni che non lo fanno.
Tony Suffolk, 66

22

Il seguente blocco dovrebbe funzionare:

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

2
ma is_authenticated (modelli sia interni che esterni) restituisce sempre True, indipendentemente dal fatto che l'utente abbia effettivamente effettuato l'accesso o meno.
Tony Suffolk, 66

Il documento dice: Attributo di sola lettura che è sempre True (al contrario di AnonymousUser.is_authenticated che è sempre False). Questo è un modo per dire se l'utente è stato autenticato. Ciò non implica alcuna autorizzazione e non verifica se l'utente è attivo o ha una sessione valida. Anche se normalmente controllerai questo attributo su request.user per scoprire se è stato popolato da AuthenticationMiddleware (che rappresenta l'utente attualmente connesso), dovresti sapere che questo attributo è True per qualsiasi istanza dell'utente.
Sopan,

Quindi, se si desidera visualizzare - utenti non autenticati come "Benvenuto Ospite" e autenticare gli utenti come "Benvenuto .USERNAME", può funzionare il seguente blocco nei modelli: {% if user.is_authenticated%} <p> Benvenuto {{user.username }} !!! </p> {% else%} <p> Benvenuto ospite !!! </p> {% endif%}
Sopan,

7

Dal tuo punto di vista:

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

Nelle tue funzioni controller aggiungi decoratore:

from django.contrib.auth.decorators import login_required
@login_required
def privateFunction(request):

ma is_authenticated (modelli sia interni che esterni) restituisce sempre True, indipendentemente dal fatto che l'utente abbia effettivamente effettuato l'accesso o meno.
Tony Suffolk, 66

meglio l'utente request.user.is_authenticatedse sai che la tua applicazione disconnetterà sempre l'utente
Tony Suffolk, 66

0

Se vuoi verificare la presenza di utenti autenticati nel tuo modello, allora:

{% if user.is_authenticated %}
    <p>Authenticated user</p>
{% else %}
    <!-- Do something which you want to do with unauthenticated user -->
{% endif %}

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.