Zoeken…


Gebruik van de flask-login-extensie

Een van de eenvoudigere manieren om een autorisatiesysteem te implementeren, is het gebruik van de flask-login- extensie. De website van het project bevat een gedetailleerde en goed geschreven quickstart, waarvan een kortere versie beschikbaar is in dit voorbeeld.

Algemeen idee

De extensie onthult een aantal functies die worden gebruikt voor:

  • gebruikers inloggen
  • gebruikers uitloggen
  • controleren of een gebruiker is ingelogd of niet en achterhalen welke gebruiker dat is

Wat het niet doet en wat u zelf moet doen:

  • biedt geen manier om gebruikers op te slaan, bijvoorbeeld in de database
  • biedt geen manier om de inloggegevens van de gebruiker te controleren, bijvoorbeeld gebruikersnaam en wachtwoord

Hieronder is een minimale set stappen nodig om alles werkend te krijgen.

Ik zou aanraden om alle auth-gerelateerde code in een aparte module of pakket te plaatsen, bijvoorbeeld auth.py Op die manier kunt u de benodigde klassen, objecten of aangepaste functies afzonderlijk maken.

Maak een LoginManager

De extensie gebruikt een LoginManager klasse die moet worden geregistreerd op uw Flask toepassingsobject.

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

Zoals eerder LoginManager kan LoginManager bijvoorbeeld een globale variabele in een afzonderlijk bestand of pakket zijn. Vervolgens kan het worden geïmporteerd in het bestand waarin het Flask object is gemaakt of in de fabrieksfunctie van uw toepassing en geïnitialiseerd.

Geef een callback op die wordt gebruikt voor het laden van gebruikers

Gebruikers worden normaal uit een database geladen. De terugbelactie moet een object retourneren dat een gebruiker vertegenwoordigt die overeenkomt met de opgegeven ID. Het moet None teruggeven als de ID niet geldig is.

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

Dit kan direct onder het maken van uw LoginManager worden gedaan.

Een klasse die uw gebruiker vertegenwoordigt

Zoals vermeld moet de callback user_loader een object retourneren dat een gebruiker vertegenwoordigt. Wat betekent dat precies? Dat object kan bijvoorbeeld een wrapper zijn rond gebruikersobjecten die zijn opgeslagen in uw database of eenvoudigweg een model uit uw database. Dat object moet de volgende methoden en eigenschappen implementeren. Dat betekent dat als de callback uw databasemodel retourneert, u ervoor moet zorgen dat de genoemde eigenschappen en methoden aan uw model worden toegevoegd.

  • is_authenticated

    Deze eigenschap moet True retourneren als de gebruiker is geverifieerd, dat wil zeggen dat deze geldige inloggegevens hebben verstrekt. U wilt ervoor zorgen dat de objecten die uw gebruikers vertegenwoordigen door de callback van user_loader geretourneerd True voor die methode zijn.

  • is_active

    Deze eigenschap moet True retourneren als dit een actieve gebruiker is. Ze zijn niet alleen geverifieerd, maar hebben ook hun account geactiveerd, niet opgeschort of een andere voorwaarde die uw toepassing heeft voor het weigeren van een account. Inactieve accounts kunnen zich niet aanmelden. Als u niet over een dergelijk mechanisme beschikt, retourneert u True van deze methode.

  • is_anonymous

    Deze eigenschap moet True retourneren als dit een anonieme gebruiker is. Dat betekent dat uw gebruikersobject dat wordt geretourneerd door de callback user_loader True moet retourneren.

  • get_id()

    Deze methode moet een unicode retourneren die deze gebruiker op unieke wijze identificeert en kan worden gebruikt om de gebruiker te laden vanuit de callback van user_loader . Merk op dat dit een unicode moet zijn - als de ID van nature een int of een ander type is, moet u deze naar unicode converteren. Als de callback user_loader objecten uit de database retourneert, retourneert deze methode hoogstwaarschijnlijk de database-ID van deze specifieke gebruiker. Dezelfde ID moet er natuurlijk voor zorgen dat de callback user_loader later dezelfde gebruiker retourneert.

Als u dingen voor uzelf gemakkelijker wilt maken (** het wordt in feite aanbevolen), kunt u van UserMixin erven in het object dat wordt geretourneerd door de callback van user_loader (vermoedelijk een databasemodel). U kunt zien hoe die methoden en eigenschappen worden uitgevoerd door standaard in deze mixin hier .

Inloggen van de gebruikers

De extensie laat de validatie van de gebruikersnaam en het wachtwoord dat door de gebruiker is ingevoerd, aan u over. In feite maakt de extensie niet uit of u een combinatie van gebruikersnaam en wachtwoord of een ander mechanisme gebruikt. Dit is een voorbeeld voor het aanmelden van gebruikers met gebruikersnaam en wachtwoord.

@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)

Over het algemeen wordt het aanmelden van gebruikers bereikt door login_user aan te roepen en een exemplaar van een object door te geven dat uw eerder genoemde gebruiker vertegenwoordigt. Zoals getoond zal dit meestal gebeuren na het ophalen van de gebruiker uit de database en het valideren van zijn inloggegevens, maar het gebruikersobject verschijnt gewoon magisch in dit voorbeeld.

Ik heb een gebruiker ingelogd, wat nu?

Het object dat wordt geretourneerd door de callback user_loader is op meerdere manieren toegankelijk.

  • In sjablonen:

    De extensie injecteert het automatisch onder de naam current_user met behulp van een sjablooncontextprocessor. Om dat gedrag uit te schakelen en uw aangepaste processor te gebruiken, add_context_processor=False in uw LoginManager constructor.

      {% if current_user.is_authenticated %}
        Hi {{ current_user.name }}!
      {% endif %}
    
  • In Python-code:

    De extensie biedt een verzoekgebonden object met de naam 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!'
    
  • Snel de toegang beperken met een decorateur Een login_required decorateur kan worden gebruikt om de toegang snel te beperken.

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

Gebruikers afmelden

Gebruikers kunnen worden uitgelogd door logout_user() aan te roepen. Het lijkt erop dat dit veilig is om te doen, zelfs als de gebruiker niet is ingelogd, zodat de @login_required decorateur waarschijnlijk kan worden weggelaten.

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

Wat gebeurt er als een gebruiker niet is aangemeld en ik toegang heb tot het object current_user ?

Standaard wordt een AnonymousUserMixin geretourneerd:

  • is_active en is_authenticated zijn False
  • is_anonymous is True
  • get_id() retourneert None

Om een ander object voor anonieme gebruikers te gebruiken, moet u een opvraagbare functie (een klasse- of fabrieksfunctie) LoginManager die anonieme gebruikers voor uw LoginManager met:

login_manager.anonymous_user = MyAnonymousUser

Wat nu?

Hiermee is de basisintroductie van de extensie afgesloten. Voor meer informatie over configuratie en extra opties wordt het ten zeerste aanbevolen om de officiële gids te lezen .

Time-out van de inlogsessie

Het is een goede gewoonte om na een bepaalde tijd een time-out te krijgen voor de ingelogde sessie, u kunt dat bereiken met 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)

De standaardlevensduur van de sessie is 31 dagen, de gebruiker moet de inlogvernieuwingsweergave opgeven in geval van een time-out.

app.permanent_session_lifetime = timedelta(minutes=5)

Bovenstaande regel zal de gebruiker dwingen om elke 5 minuten opnieuw in te loggen.



Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow