Flask
Auktorisation och autentisering
Sök…
Med flask-inloggningsförlängning
Ett av de enklare sätten att implementera ett auktoriseringssystem är att använda flask-inloggningsförlängningen . Projektets webbplats innehåller en detaljerad och välskriven snabbstart, av vilken en kortare version finns tillgänglig i det här exemplet.
Allmän uppfattning
Tillägget visar en uppsättning funktioner som används för:
- loggar in användare
- loggar ut användare
- kontrollera om en användare är inloggad eller inte och ta reda på vilken användare som är den
Vad det inte gör och vad du måste göra på egen hand:
- ger inte ett sätt att lagra användare, till exempel i databasen
- ger inte ett sätt att kontrollera användarens referenser, till exempel användarnamn och lösenord
Nedan finns en minimal uppsättning steg som krävs för att allt ska fungera.
Jag rekommenderar att du lägger all godkänd kod i en separat modul eller paket, till exempel auth.py
. På så sätt kan du skapa nödvändiga klasser, objekt eller anpassade funktioner separat.
Skapa en LoginManager
LoginManager
använder en LoginManager
klass som måste registreras på ditt Flask
applikationsobjekt.
from flask_login import LoginManager
login_manager = LoginManager()
login_manager.init_app(app) # app is a Flask object
Som tidigare LoginManager
kan LoginManager
till exempel vara en global variabel i en separat fil eller paket. Sedan kan det importeras i filen där Flask
objektet skapas eller i din applikationsfabriksfunktion och initialiseras.
Ange ett återuppringning som används för att ladda användare
En användare kommer normalt att laddas från en databas. Återuppringningen måste returnera ett objekt som representerar en användare som motsvarar det angivna ID. Det ska returnera None
om ID: n inte är giltig.
@login_manager.user_loader
def load_user(user_id):
return User.get(user_id) # Fetch the user from the database
Detta kan göras direkt nedan du skapar din LoginManager
.
En klass som representerar din användare
Såsom nämnts user_loader
återuppringning av user_loader
returnera ett objekt som representerar en användare. Vad betyder det exakt? Det objektet kan till exempel vara ett omslag runt användarobjekt lagrat i din databas eller helt enkelt direkt en modell från din databas. Detta objekt måste implementera följande metoder och egenskaper. Det betyder att om återuppringningen returnerar din databasmodell måste du se till att de nämnda egenskaperna och metoderna läggs till din modell.
is_authenticated
Den här egenskapen ska returnera
True
om användaren är autentiserad, dvs de har tillhandahållit giltiga referenser. Du vill se till att de objekt som representerar dina användare som returneras avuser_loader
återuppringning returnerarTrue
för den metoden.is_active
Den här egenskapen ska returnera True om detta är en aktiv användare - förutom att de har autentiserats har de också aktiverat sitt konto, inte stängts av eller något villkor som din ansökan har för att avvisa ett konto. Inaktiva konton kanske inte loggar in. Om du inte har en sådan mekanism närvarande returnerar
True
från den här metoden.is_anonymous
Den här egenskapen ska returnera True om detta är en anonym användare. Det betyder att ditt användarobjekt som returneras av
user_loader
återuppringning ska returneraTrue
.get_id()
Den här metoden måste returnera en unicode som identifierar den här användaren på ett unikt sätt och kan användas för att ladda användaren från återuppringning av
user_loader
. Observera att det här måste vara en unicode - om ID är naturligtvis en int eller någon annan typ, måste du konvertera det till unicode. Om återuppringning avuser_loader
returnerar objekt från databasen kommer denna metod troligen att returnera databas-ID för denna användare. Samma ID borde naturligtvis göra attuser_loader
återuppringning returnerar samma användare senare.
Om du vill göra det lättare för dig själv (** rekommenderas det faktiskt) kan du ärva från UserMixin
i det objekt som returneras av user_loader
(förmodligen en databasmodell). Du kan se hur dessa metoder och egenskaper implementeras som standard i denna mixin här .
Loggar in användare
Tillägget lämnar valideringen av användarnamn och lösenord som användaren har angett till dig. I själva verket bryr sig tillägget inte om du använder ett användarnamn och lösenordskombination eller annan mekanism. Detta är ett exempel för att logga in användare med användarnamn och lösenord.
@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)
Generellt genomförs inloggning genom att ringa inloggningsanvändare och skicka en instans av ett objekt som representerar din användare som tidigare nämnts till det. Som visas kommer detta vanligtvis att hända efter att hämtat användaren från databasen och validerat hans referenser, men användarobjektet visas bara magiskt i det här exemplet.
Jag har loggat in en användare, vad nu?
Det objekt som returneras av user_loader
kan nås på flera sätt.
I mallar:
Tillägget injicerar det automatiskt under namnet
current_user
med encurrent_user
. För att inaktivera det beteendet och använda din anpassade processor, sättadd_context_processor=False
i dinLoginManager
konstruktör.{% if current_user.is_authenticated %} Hi {{ current_user.name }}! {% endif %}
I Python-kod:
Tillägget tillhandahåller ett förfrågningsbundet objekt som heter
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!'
Begränsa åtkomst snabbt med en dekoratör En
login_required
dekoratör kan användas för att begränsa åtkomst snabbt.from flask_login import login_required @app.route("/settings") @login_required def settings(): pass
Loggar ut användare
Användare kan loggas ut genom att ringa logout_user()
. Det verkar som det är säkert att göra det även om användaren inte är inloggad så att @login_required
dekoratören troligtvis kan utelämnas.
@app.route("/logout")
@login_required
def logout():
logout_user()
return redirect(somewhere)
Vad händer om en användare inte är inloggad och jag får åtkomst till det current_user
?
Genom defult returneras ett AnonymousUserMixin :
-
is_active
ochis_authenticated
ärFalse
-
is_anonymous
ärTrue
-
get_id()
returnerarNone
För att använda ett annat objekt för anonyma användare tillhandahålls en utrullning (antingen en klass- eller fabriksfunktion) som skapar anonyma användare till din LoginManager
med:
login_manager.anonymous_user = MyAnonymousUser
Vad händer nu?
Detta avslutar den grundläggande introduktionen till tillägget. För att lära dig mer om konfiguration och ytterligare alternativ rekommenderas starkt att du läser den officiella guiden .
Avbryt inloggningssessionen
Det är bra att spela in inloggad session efter specifik tid, du kan uppnå det med 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)
Standard sessionens livslängd är 31 dagar, användaren måste ange inloggningsuppdateringsvyn vid timeout.
app.permanent_session_lifetime = timedelta(minutes=5)
Ovanstående linje kommer att tvinga användaren att logga in om var 5: e minut.