Ricerca…


Usando l'estensione login-flask

Uno dei modi più semplici per implementare un sistema di autorizzazione consiste nell'utilizzare l'estensione login-flask . Il sito web del progetto contiene un quickstart dettagliato e ben scritto, di cui una versione più breve è disponibile in questo esempio.

Idea generale

L'estensione espone un insieme di funzioni utilizzate per:

  • registrazione utenti in
  • disconnettendo gli utenti
  • verificare se un utente è connesso o meno e scoprire quale utente è quello

Cosa non fa e cosa devi fare da solo:

  • non fornisce un modo di memorizzare gli utenti, ad esempio nel database
  • non fornisce un modo per controllare le credenziali dell'utente, ad esempio nome utente e password

Di seguito c'è una serie minima di passaggi necessari per far funzionare tutto.

Raccomanderei di inserire tutto il codice relativo auth.py in un modulo o pacchetto separato, ad esempio auth.py In questo modo è possibile creare separatamente classi, oggetti o funzioni personalizzate.

Creare un LoginManager

L'estensione utilizza una classe LoginManager che deve essere registrata sull'oggetto dell'applicazione Flask .

from flask_login import LoginManager
login_manager = LoginManager()
login_manager.init_app(app) # app is a Flask object

Come accennato in precedenza, LoginManager può essere ad esempio una variabile globale in un file o pacchetto separato. Quindi può essere importato nel file in cui è stato creato l'oggetto Flask o nella funzione di fabbrica dell'applicazione e inizializzato.

Specifica una richiamata utilizzata per il caricamento degli utenti

Un utente verrà normalmente caricato da un database. Il callback deve restituire un oggetto che rappresenta un utente corrispondente all'ID fornito. Dovrebbe restituire None se l'ID non è valido.

@login_manager.user_loader
def load_user(user_id):
    return User.get(user_id) # Fetch the user from the database

Questo può essere fatto direttamente sotto la creazione del tuo LoginManager .

Una classe che rappresenta il tuo utente

Come accennato, il callback user_loader deve restituire un oggetto che rappresenta un utente. Cosa significa esattamente? Ad esempio, tale oggetto può essere un wrapper attorno agli oggetti utente memorizzati nel database o semplicemente direttamente un modello dal database. Questo oggetto deve implementare i seguenti metodi e proprietà. Ciò significa che se il callback restituisce il modello del database, è necessario assicurarsi che le proprietà e i metodi citati vengano aggiunti al modello.

  • is_authenticated

    Questa proprietà dovrebbe restituire True se l'utente è autenticato, cioè hanno fornito credenziali valide. Dovrai assicurarti che gli oggetti che rappresentano i tuoi utenti restituiti dal callback user_loader restituiscano True per quel metodo.

  • is_active

    Questa proprietà dovrebbe restituire True se questo è un utente attivo - oltre ad essere autenticato, hanno anche attivato il loro account, non sono stati sospesi, o qualsiasi condizione che l'applicazione ha per il rifiuto di un account. Gli account inattivi potrebbero non accedere. Se non si dispone di un meccanismo presente, restituire True da questo metodo.

  • is_anonymous

    Questa proprietà dovrebbe restituire True se si tratta di un utente anonimo. Ciò significa che l'oggetto utente restituito dalla callback user_loader deve restituire True .

  • get_id()

    Questo metodo deve restituire un Unicode che identifica in modo univoco questo utente e può essere utilizzato per caricare l'utente dal callback user_loader . Nota che questo deve essere un unicode: se l'ID è nativamente un int o qualche altro tipo, dovrai convertirlo in unicode. Se il callback user_loader restituisce oggetti dal database, questo metodo restituirà molto probabilmente l'ID del database di questo particolare utente. Lo stesso ID dovrebbe ovviamente causare il callback user_loader per restituire lo stesso utente in un secondo momento.

Se si desidera semplificare le cose da soli (** è in realtà consigliato) è possibile ereditare da UserMixin l'oggetto restituito dal callback user_loader (presumibilmente un modello di database). Puoi vedere come questi metodi e proprietà sono implementati di default in questo mixin qui .

Registrazione degli utenti in

L'estensione lascia la convalida del nome utente e della password immessi dall'utente all'utente. In effetti l'estensione non interessa se si utilizza una combinazione di nome utente e password o altro meccanismo. Questo è un esempio per la registrazione degli utenti nell'uso di username e password.

@app.route('/login', methods=['GET', 'POST'])
def login():
    # Here we use a class of some kind to represent and validate our
    # client-side form data. For example, WTForms is a library that will
    # handle this for us, and we use a custom LoginForm to validate.
    form = LoginForm()
    if form.validate_on_submit():
        # Login and validate the user.
        # user should be an instance of your `User` class
        login_user(user)

        flask.flash('Logged in successfully.')

        next = flask.request.args.get('next')
        # is_safe_url should check if the url is safe for redirects.
        # See http://flask.pocoo.org/snippets/62/ for an example.
        if not is_safe_url(next):
            return flask.abort(400)

        return flask.redirect(next or flask.url_for('index'))
    return flask.render_template('login.html', form=form)

In generale, gli utenti di logging si ottengono chiamando login_user e passando un'istanza di un oggetto che rappresenta l'utente menzionato in precedenza. Come mostrato, ciò accade di solito dopo aver recuperato l'utente dal database e aver convalidato le sue credenziali, tuttavia l'oggetto utente appare magicamente in questo esempio.

Ho effettuato l'accesso a un utente, e ora?

L'oggetto restituito dal callback user_loader è accessibile in più modi.

  • Nei modelli:

    L'estensione la inietta automaticamente sotto il nome current_user usando un processore di contesto del modello. Per disabilitare tale comportamento e utilizzare il set di processori personalizzato add_context_processor=False nel costruttore di LoginManager .

      {% if current_user.is_authenticated %}
        Hi {{ current_user.name }}!
      {% endif %}
    
  • Nel codice Python:

    L'estensione fornisce un oggetto associato alla richiesta denominato current_user .

      from flask_login import current_user    
    
      @app.route("/hello")
      def hello():
          # Assuming that there is a name property on your user object
          # returned by the callback
          if current_user.is_authenticated:
              return 'Hello %s!' % current_user.name 
          else:
              return 'You are not logged in!'
    
  • Limitare l'accesso rapidamente usando un decoratore Un decoratore login_required può essere utilizzato per limitare l'accesso rapidamente.

      from flask_login import login_required
    
      @app.route("/settings")
      @login_required
      def settings():
          pass
    

Registrazione degli utenti

Gli utenti possono essere disconnessi chiamando logout_user() . Sembra che sia sicuro farlo anche se l'utente non ha effettuato l'accesso in modo che il decoratore @login_required possa molto probabilmente essere ommited.

@app.route("/logout")
@login_required
def logout():
    logout_user()
    return redirect(somewhere)

Cosa succede se un utente non ha effettuato l'accesso e current_user all'oggetto current_user ?

Per difetto viene restituito un AnonymousUserMixin :

  • is_active e is_authenticated sono False
  • is_anonymous è True
  • get_id() restituisce None

Per utilizzare un oggetto diverso per gli utenti anonimi, è possibile chiamare un oggetto chiamabile (di classe o di fabbrica) che crea utenti anonimi su LoginManager con:

login_manager.anonymous_user = MyAnonymousUser

Cosa succederà?

Questo conclude l'introduzione di base all'estensione. Per ulteriori informazioni sulla configurazione e sulle opzioni aggiuntive, si consiglia vivamente di leggere la guida ufficiale .

Timeout della sessione di accesso

È buona norma interrompere la sessione di accesso dopo un determinato periodo di tempo, è possibile farlo con Flask-Login.

from flask import Flask, session
from datetime import timedelta
from flask_login import LoginManager, login_require, login_user, logout_user

# Create Flask application

app = Flask(__name__) 

# Define Flask-login configuration 

login_mgr = LoginManager(app)
login_mgr.login_view = 'login'
login_mgr.refresh_view = 'relogin'
login_mgr.needs_refresh_message = (u"Session timedout, please re-login")
login_mgr.needs_refresh_message_category = "info"


@app.before_request
def before_request():
    session.permanent = True
    app.permanent_session_lifetime = timedelta(minutes=5)

La durata predefinita della sessione è di 31 giorni, l'utente deve specificare la vista di aggiornamento del login in caso di timeout.

app.permanent_session_lifetime = timedelta(minutes=5)

Sopra la linea costringerà l'utente a riconnettersi ogni 5 minuti.



Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow