Szukaj…


Używanie rozszerzenia login flask

Jednym z prostszych sposobów implementacji systemu autoryzacji jest użycie rozszerzenia login-flask . Strona internetowa projektu zawiera szczegółowy i dobrze napisany szybki start, którego krótsza wersja jest dostępna w tym przykładzie.

Główny pomysł

Rozszerzenie udostępnia zestaw funkcji używanych do:

  • logowanie użytkowników
  • wylogowywanie użytkowników
  • sprawdzanie, czy użytkownik jest zalogowany czy nie, i sprawdzanie, który to użytkownik

Czego nie robi i co musisz zrobić sam:

  • nie zapewnia sposobu przechowywania użytkowników, na przykład w bazie danych
  • nie zapewnia sposobu sprawdzania poświadczeń użytkownika, na przykład nazwy użytkownika i hasła

Poniżej znajduje się minimalny zestaw kroków niezbędnych do działania.

Zalecam umieszczenie całego kodu związanego z uwierzytelnianiem w oddzielnym module lub pakiecie, na przykład auth.py W ten sposób możesz osobno utworzyć niezbędne klasy, obiekty lub funkcje niestandardowe.

Utwórz LoginManager

Rozszerzenie używa klasy LoginManager którą należy zarejestrować w obiekcie aplikacji Flask .

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

Jak wspomniano wcześniej, LoginManager może na przykład być zmienną globalną w osobnym pliku lub pakiecie. Następnie można go zaimportować do pliku, w którym obiekt Flask jest tworzony, lub do funkcji fabryki aplikacji i zainicjować ją.

Określ wywołanie zwrotne używane do ładowania użytkowników

Użytkownicy zwykle będą ładowani z bazy danych. Oddzwonienie musi zwrócić obiekt reprezentujący użytkownika odpowiadającego podanemu identyfikatorowi. Powinien zwrócić None jeśli identyfikator jest niepoprawny.

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

Można to zrobić bezpośrednio poniżej podczas tworzenia LoginManager .

Klasa reprezentująca twojego użytkownika

Jak wspomniano, wywołanie zwrotne user_loader musi zwrócić obiekt reprezentujący użytkownika. Co to dokładnie znaczy? Obiekt ten może na przykład być opakowaniem wokół obiektów użytkownika przechowywanych w bazie danych lub po prostu bezpośrednio modelem z bazy danych. Ten obiekt musi implementować następujące metody i właściwości. Oznacza to, że jeśli wywołanie zwrotne zwróci model bazy danych, musisz upewnić się, że wspomniane właściwości i metody zostały dodane do modelu.

  • is_authenticated

    Ta właściwość powinna zwracać wartość True jeśli użytkownik jest uwierzytelniony, tzn. Podał prawidłowe poświadczenia. Należy upewnić się, że obiekty reprezentujące użytkowników zwrócone przez wywołanie zwrotne user_loader zwracają wartość True dla tej metody.

  • is_active

    Ta właściwość powinna zwracać wartość Prawda, jeśli jest to aktywny użytkownik - oprócz uwierzytelnienia aktywowali oni także swoje konto, nie zostali zawieszeni ani nie spełnili żadnych warunków dotyczących odrzucenia konta przez aplikację. Nieaktywne konta mogą się nie logować. Jeśli nie masz takiego mechanizmu, zwróć wartość True z tej metody.

  • is_anonymous

    Ta właściwość powinna zwrócić wartość True, jeśli jest to anonimowy użytkownik. Oznacza to, że obiekt użytkownika zwrócony przez wywołanie zwrotne user_loader powinien zwrócić wartość True .

  • get_id()

    Ta metoda musi zwrócić kod Unicode, który jednoznacznie identyfikuje tego użytkownika, i można go użyć do załadowania użytkownika z wywołania zwrotnego user_loader . Pamiętaj, że musi to być Unicode - jeśli ID jest natywnie int lub innego typu, musisz przekonwertować go na Unicode. Jeśli wywołanie zwrotne user_loader zwraca obiekty z bazy danych, ta metoda najprawdopodobniej zwróci identyfikator bazy danych tego konkretnego użytkownika. Ten sam identyfikator powinien oczywiście powodować, że wywołanie zwrotne user_loader zwróci później tego samego użytkownika.

Jeśli chcesz ułatwić sobie pracę (** jest to faktycznie zalecane), możesz dziedziczyć po UserMixin w obiekcie zwróconym przez wywołanie zwrotne user_loader (prawdopodobnie model bazy danych). Można zobaczyć, jak te metody i właściwości są wdrażane domyślnie w tym wstawek tutaj .

Logowanie użytkowników

Rozszerzenie pozostawia sprawdzenie poprawności nazwy użytkownika i hasła wprowadzonych przez użytkownika. W rzeczywistości rozszerzenie nie ma znaczenia, jeśli używasz kombinacji nazwy użytkownika i hasła lub innego mechanizmu. To jest przykład logowania użytkowników przy użyciu nazwy użytkownika i hasła.

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

Zasadniczo logowanie użytkowników odbywa się poprzez wywołanie login_user i przekazanie instancji obiektu reprezentującego wspomnianego wcześniej użytkownika. Jak pokazano, zwykle dzieje się to po pobraniu użytkownika z bazy danych i sprawdzeniu jego poświadczeń, jednak obiekt użytkownika po prostu magicznie pojawia się w tym przykładzie.

Zalogowałem użytkownika, co teraz?

Do obiektu zwróconego przez wywołanie zwrotne user_loader można uzyskać dostęp na wiele sposobów.

  • W szablonach:

    Rozszerzenie automatycznie wstrzykuje je pod nazwą current_user przy użyciu procesora kontekstowego szablonu. Aby wyłączyć to zachowanie i użyć niestandardowego procesora, ustaw add_context_processor=False w konstruktorze LoginManager .

      {% if current_user.is_authenticated %}
        Hi {{ current_user.name }}!
      {% endif %}
    
  • W kodzie Python:

    Rozszerzenie udostępnia obiekt związany z żądaniem o nazwie 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!'
    
  • login_required ograniczanie dostępu za pomocą dekoratora Za login_required dekoratora login_required można szybko ograniczyć dostęp.

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

Wylogowywanie użytkowników

Użytkownicy mogą zostać wylogowani poprzez wywołanie logout_user() . Wygląda na to, że jest to bezpieczne, nawet jeśli użytkownik nie jest zalogowany, więc dekorator @login_required może najprawdopodobniej zostać pominięty.

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

Co się stanie, jeśli użytkownik nie będzie zalogowany i current_user dostęp do obiektu current_user ?

Defult zwraca AnonymousUserMixin :

  • is_active i is_authenticatedFalse
  • is_anonymous to True
  • get_id() zwraca None

Aby użyć innego obiektu dla anonimowych użytkowników, należy udostępnić wywołanie (funkcję klasową lub fabryczną), które tworzy anonimowych użytkowników do LoginManager pomocą:

login_manager.anonymous_user = MyAnonymousUser

Co następne?

To kończy podstawowe wprowadzenie do rozszerzenia. Aby dowiedzieć się więcej na temat konfiguracji i dodatkowych opcji, zaleca się przeczytanie oficjalnego przewodnika .

Przekroczono limit czasu sesji logowania

Dobrą praktyką jest limit czasu zalogowanej sesji po określonym czasie, możesz to osiągnąć dzięki 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)

Domyślny czas życia sesji wynosi 31 dni, w przypadku przekroczenia limitu czasu użytkownik musi określić widok odświeżania logowania.

app.permanent_session_lifetime = timedelta(minutes=5)

Powyższa linia zmusi użytkownika do ponownego logowania co 5 minut.



Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow