Flask
Авторизация и аутентификация
Поиск…
Использование расширения для флажков
Один из простых способов внедрения системы авторизации - использование расширения для флажков. Веб-сайт проекта содержит подробный и хорошо написанный быстрый старт, более короткая версия которого доступна в этом примере.
Главная идея
Расширение предоставляет набор функций, используемых для:
- регистрация пользователей в
- выключение пользователей
- проверять, зарегистрирован ли пользователь или нет, и выяснить, какой пользователь это
Что он не делает и что вам нужно делать самостоятельно:
- не обеспечивает способ хранения пользователей, например, в базе данных
- не предоставляет способ проверки учетных данных пользователя, например, имя пользователя и пароль
Ниже приведен минимальный набор шагов, необходимых для того, чтобы все работало.
Я бы рекомендовал поместить весь код, связанный с auth, в отдельный модуль или пакет, например auth.py
Таким образом, вы можете создавать необходимые классы, объекты или настраиваемые функции отдельно.
Создайте LoginManager
Расширение использует класс LoginManager
который должен быть зарегистрирован на вашем объекте приложения Flask
.
from flask_login import LoginManager
login_manager = LoginManager()
login_manager.init_app(app) # app is a Flask object
Как уже упоминалось ранее, LoginManager
может быть, например, глобальной переменной в отдельном файле или пакете. Затем его можно импортировать в файл, в котором создается объект Flask
или в вашей фабричной функции приложения и инициализирован.
Укажите обратный вызов, используемый для загрузки пользователей
Обычно пользователи загружаются из базы данных. Обратный вызов должен возвращать объект, который представляет пользователя, соответствующего предоставленному идентификатору. Он должен вернуть None
если идентификатор недействителен.
@login_manager.user_loader
def load_user(user_id):
return User.get(user_id) # Fetch the user from the database
Это можно сделать непосредственно, создав свой LoginManager
.
Класс, представляющий пользователя
Как упоминалось, user_loader
вызов user_loader
должен возвращать объект, который представляет пользователя. Что именно это значит? Этот объект может быть, например, оберткой вокруг пользовательских объектов, хранящихся в вашей базе данных, или просто непосредственно модель из вашей базы данных. Этот объект должен реализовать следующие методы и свойства. Это означает, что если обратный вызов возвращает вашу модель базы данных, вам необходимо убедиться, что указанные свойства и методы добавлены в вашу модель.
is_authenticated
Это свойство должно возвращать
True
если пользователь аутентифицирован, то есть предоставил действительные учетные данные. Вы хотите, чтобы объекты, представляющие ваших пользователей, возвращаемыеuser_loader
вызовомuser_loader
возвращаютTrue
для этого метода.is_active
Это свойство должно возвращать True, если это активный пользователь - помимо аутентификации, они также активировали свою учетную запись, а не были приостановлены, или какое-либо условие, которое ваше приложение отклоняет для учетной записи. Неактивные учетные записи не могут войти в систему. Если у вас нет такого механизма, возвращайте
True
из этого метода.is_anonymous
Это свойство должно возвращать True, если это анонимный пользователь. Это означает, что ваш пользовательский объект, возвращаемый
user_loader
вызовомuser_loader
должен вернутьTrue
.get_id()
Этот метод должен возвращать unicode, который однозначно идентифицирует этого пользователя и может использоваться для загрузки пользователя из обратного вызова
user_loader
. Обратите внимание, что это должен быть unicode - если идентификатор изначально является int или каким-либо другим типом, вам нужно будет преобразовать его в unicode. Еслиuser_loader
вызовuser_loader
возвращает объекты из базы данных, этот метод скорее всего вернет идентификатор базы данных этого конкретного пользователя. Один и тот же идентификатор должен, разумеется, вызватьuser_loader
вызовuser_loader
дляuser_loader
возвращения того же пользователя.
Если вы хотите облегчить себе задачу (** на самом деле рекомендуется), вы можете наследовать от UserMixin
в объекте, возвращаемом user_loader
вызовом user_loader
(предположительно, модель базы данных). Вы можете увидеть, как эти методы и свойства реализованы по умолчанию в этом mixin здесь .
Регистрация пользователей в
Расширение оставляет подтверждение имени пользователя и пароля, введенных пользователем. На самом деле расширение не волнует, если вы используете комбинацию имени пользователя и пароля или другой механизм. Это пример регистрации пользователей при использовании имени пользователя и пароля.
@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)
В общем случае регистрация пользователей осуществляется путем вызова login_user и передачи экземпляра объекта, представляющего вашего пользователя, упомянутого ранее. Как показано, это обычно происходит после извлечения пользователя из базы данных и проверки его учетных данных, однако в этом примере объект пользователя просто волшебным образом появляется.
Я зарегистрировал пользователя, что теперь?
Объект, возвращаемый user_loader
вызовом user_loader
может быть доступен несколькими способами.
В шаблонах:
Расширение автоматически вводит его под именем
current_user
с использованием контекстного процессора шаблонов. Чтобы отключить это поведение и использовать свой настраиваемый процессор,add_context_processor=False
в свой конструкторLoginManager
.{% if current_user.is_authenticated %} Hi {{ current_user.name }}! {% endif %}
В коде Python:
Расширение предоставляет объект с привязкой к запросу, называемый
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
украшенияlogin_required
можно использовать для быстрого доступа к доступу.from flask_login import login_required @app.route("/settings") @login_required def settings(): pass
Запуск пользователей
Пользователи могут быть выведены из системы, вызывая logout_user()
. Похоже, что это безопасно, даже если пользователь не @login_required
в систему, поэтому декоратор @login_required
скорее всего, будет ограничен.
@app.route("/logout")
@login_required
def logout():
logout_user()
return redirect(somewhere)
Что произойдет, если пользователь не войдет в систему, и я обращаюсь к объекту current_user
?
Дефолтом будет возвращен элемент AnonymousUserMixin :
-
is_active
иis_authenticated
-False
-
is_anonymous
-True
-
get_id()
возвращаетNone
Чтобы использовать другой объект для анонимных пользователей, вы можете LoginManager
(функцию класса или фабрику), которая создает анонимных пользователей для вашего LoginManager
с помощью:
login_manager.anonymous_user = MyAnonymousUser
Что дальше?
Это завершает базовое введение в расширение. Чтобы узнать больше о настройке и дополнительных параметрах, настоятельно рекомендуется ознакомиться с официальным руководством .
Завершение сеанса входа в систему
Хорошая практика тайм-аута после входа в систему после определенного времени, вы можете достичь этого с помощью 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)
Срок службы сеанса по умолчанию - 31 день, пользователю необходимо указать вид обновления входа в случае тайм-аута.
app.permanent_session_lifetime = timedelta(minutes=5)
Вышеуказанная строка заставит пользователя повторно зарегистрироваться каждые 5 минут.