Flask
Autorisierung und Authentifizierung
Suche…
Flask-login extension verwenden
Eine der einfacheren Methoden zur Implementierung eines Autorisierungssystems ist die Verwendung der Erweiterung für die Flaschenanmeldung . Die Projektwebsite enthält einen detaillierten und gut geschriebenen Schnellstart, von dem eine kürzere Version in diesem Beispiel verfügbar ist.
Grund Idee
Die Erweiterung macht eine Reihe von Funktionen verfügbar, die für Folgendes verwendet werden:
- Benutzer anmelden
- Benutzer abmelden
- Prüfen, ob ein Benutzer angemeldet ist oder nicht, und herausfinden, welcher Benutzer das ist
Was es nicht tut und was Sie alleine tun müssen:
- bietet keine Möglichkeit zum Speichern der Benutzer, beispielsweise in der Datenbank
- bietet keine Möglichkeit, die Anmeldeinformationen des Benutzers zu überprüfen, z. B. Benutzername und Kennwort
Unten finden Sie ein Minimum an Schritten, um alles zum Laufen zu bringen.
Ich würde empfehlen, den gesamten auth-bezogenen Code in einem separaten Modul oder Paket zu platzieren, beispielsweise auth.py
Auf diese Weise können Sie die erforderlichen Klassen, Objekte oder benutzerdefinierten Funktionen separat erstellen.
Erstellen Sie einen LoginManager
Die Erweiterung verwendet eine LoginManager
Klasse, die in Ihrem Flask
Anwendungsobjekt registriert werden muss.
from flask_login import LoginManager
login_manager = LoginManager()
login_manager.init_app(app) # app is a Flask object
Wie bereits erwähnt, kann LoginManager
beispielsweise eine globale Variable in einer separaten Datei oder einem separaten Paket sein. Dann kann es in die Datei importiert werden, in der das Flask
Objekt erstellt wird, oder in Ihrer Application Factory-Funktion und initialisiert werden.
Geben Sie einen Rückruf für das Laden von Benutzern an
Ein Benutzer wird normalerweise aus einer Datenbank geladen. Der Rückruf muss ein Objekt zurückgeben, das einen der angegebenen ID entsprechenden Benutzer darstellt. Es sollte None
wenn die ID nicht gültig ist.
@login_manager.user_loader
def load_user(user_id):
return User.get(user_id) # Fetch the user from the database
Dies kann direkt unterhalb des LoginManager
.
Eine Klasse, die Ihren Benutzer darstellt
Wie bereits erwähnt, muss der Callback des user_loader
ein Objekt zurückgeben, das einen Benutzer darstellt. Was heißt das genau? Dieses Objekt kann beispielsweise ein Wrapper für Benutzerobjekte sein, die in Ihrer Datenbank gespeichert sind, oder einfach direkt ein Modell aus Ihrer Datenbank. Dieses Objekt muss die folgenden Methoden und Eigenschaften implementieren. Das bedeutet, wenn der Rückruf Ihr Datenbankmodell zurückgibt, müssen Sie sicherstellen, dass die genannten Eigenschaften und Methoden zu Ihrem Modell hinzugefügt werden.
is_authenticated
Diese Eigenschaft sollte
True
wenn der Benutzer authentifiziert ist, dh gültige Anmeldeinformationen angegeben haben. Sie müssen sicherstellen, dass die Objekte, die Ihre Benutzer darstellen, die vomuser_loader
Callback zurückgegeben werden, für diese MethodeTrue
.is_active
Diese Eigenschaft sollte "True" zurückgeben, wenn es sich um einen aktiven Benutzer handelt. Zusätzlich zur Authentifizierung haben sie auch ihr Konto aktiviert, wurden nicht gesperrt oder eine Bedingung, die Ihre Anwendung zum Ablehnen eines Kontos hat. Inaktive Konten können sich möglicherweise nicht anmelden. Wenn ein solcher Mechanismus nicht vorhanden ist, wird
True
von dieser Methode zurückgegeben.is_anonymous
Diese Eigenschaft sollte True zurückgeben, wenn dies ein anonymer Benutzer ist. Das bedeutet, dass Ihr Benutzerobjekt, das vom
user_loader
Callback zurückgegeben wird,True
.get_id()
Diese Methode muss einen Unicode zurückgeben, der diesen Benutzer eindeutig identifiziert, und kann verwendet werden, um den Benutzer aus dem
user_loader
Callback zu laden. Beachten Sie, dass dies ein Unicode sein muss. Wenn die ID nativ ein int oder ein anderer Typ ist, müssen Sie sie in Unicode konvertieren. Wenn deruser_loader
Callback Objekte aus der Datenbankuser_loader
gibt diese Methode höchstwahrscheinlich die Datenbank-ID dieses bestimmten Benutzers zurück. Die gleiche ID sollte natürlich dazu führen, dass deruser_loader
Callback später denselben Benutzeruser_loader
.
Wenn Sie die Dinge einfacher machen möchten (** wird empfohlen), können Sie von UserMixin
in das Objekt erben, das vom user_loader
Callback zurückgegeben wird (vermutlich ein Datenbankmodell). Sie können hier sehen, wie diese Methoden und Eigenschaften standardmäßig in diesem Mixin implementiert werden .
Anmelden der Benutzer
Die Erweiterung hinterlässt die Gültigkeit des vom Benutzer eingegebenen Benutzernamens und Kennworts. In der Tat ist es der Erweiterung egal, ob Sie eine Kombination aus Benutzername und Passwort oder einen anderen Mechanismus verwenden. Dies ist ein Beispiel für das Anmelden von Benutzern mit Benutzername und Kennwort.
@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)
Im Allgemeinen wird das Anmelden von Benutzern durch Aufrufen von login_user und Übergeben einer Instanz eines Objekts, das Ihren zuvor erwähnten Benutzer darstellt, durchgeführt. Wie gezeigt, geschieht dies normalerweise, nachdem der Benutzer aus der Datenbank abgerufen und seine Anmeldeinformationen überprüft wurden. In diesem Beispiel erscheint das Benutzerobjekt jedoch nur magisch.
Ich habe einen Benutzer angemeldet, was jetzt?
Auf das vom user_loader
Callback zurückgegebene Objekt kann auf mehrere Arten zugegriffen werden.
In Vorlagen:
Die Erweiterung fügt sie automatisch unter dem Namen
current_user
mit einem Template-Kontextprozessor ein. Um dieses Verhalten zu deaktivieren und Ihren benutzerdefinierten Prozessoradd_context_processor=False
setzen Sieadd_context_processor=False
in IhremLoginManager
Konstruktor.{% if current_user.is_authenticated %} Hi {{ current_user.name }}! {% endif %}
In Python-Code:
Die Erweiterung stellt ein anforderungsgebundenes Objekt namens
current_user
bereit.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!'
Schneller Zugriff mit einem Dekorator
login_required
Mit einemlogin_required
Dekorator kann der Zugriff schnell eingeschränkt werden.from flask_login import login_required @app.route("/settings") @login_required def settings(): pass
Benutzer abmelden
Benutzer können durch Aufruf von logout_user()
abgemeldet werden. Es scheint, dass dies auch dann sicher ist, wenn der Benutzer nicht angemeldet ist, so dass der @login_required
Dekorateur höchstwahrscheinlich ausgelassen werden kann.
@app.route("/logout")
@login_required
def logout():
logout_user()
return redirect(somewhere)
Was passiert, wenn ein Benutzer nicht angemeldet ist und ich auf das Objekt current_user
zugreife?
Bei defult wird ein AnonymousUserMixin zurückgegeben:
-
is_active
undis_authenticated
sindFalse
-
is_anonymous
istTrue
-
get_id()
liefertNone
Um ein anderes Objekt für anonyme Benutzer zu verwenden, stellen Sie eine aufrufbare Funktion (entweder eine Klassen- oder eine Factory-Funktion) LoginManager
mit der anonyme Benutzer für Ihren LoginManager
werden:
login_manager.anonymous_user = MyAnonymousUser
Was als nächstes?
Damit ist die grundlegende Einführung in die Erweiterung abgeschlossen. Um mehr über die Konfiguration und zusätzliche Optionen zu erfahren, wird dringend empfohlen, das offizielle Handbuch zu lesen .
Zeitlimit für die Anmeldesitzung
Es ist empfehlenswert, die Sitzung nach einer bestimmten Zeit abzumelden, dies kann mit Flask-Login erreicht werden.
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)
Die Standard-Sitzungsdauer beträgt 31 Tage. Der Benutzer muss die Anmeldeaktualisierungsansicht angeben, wenn das Zeitlimit überschritten wird.
app.permanent_session_lifetime = timedelta(minutes=5)
Über der obigen Zeile wird der Benutzer alle 5 Minuten erneut angemeldet.