Для расширенных возможностей
авторизации, во Flask, существует расширение
Flask-Login
(документация,
исходники
с примером).
Что делает это расширение:
Когда приложение полностью сконфигурировано, необходимо передать его в LoginManager:
В общих чертах
Расширение Flask-Login предназначено для упрощения управления сессиями пользователей и решает типичные задачи, такие как вход/выход, запоминание сессий на определённый срок.Что делает это расширение:
- Хранит ID залогинившихся пользователей внутри сессии и позволяет достаточно просто управлять их входом/выходом.
- Позволяет управлять доступом пользователей к представлениям в зависимости от того, залогинились они или нет.
- Реализует функцию "запомнить меня".
- Не навязывает использование конкретных способов хранения данных о пользователях.
- Не ограничивает в выборе способа авторизации и ничего не мешает использовать логин/пароль, OpenID или любой другой способ.
- Не берет на себя разграничением прав в зависимости от залогинности пользователя.
- Не выполняет регистрацию пользователей и восстановление пароля.
Начало использования
Первое что нужно сделать, для начала работы с расширением, это создать в любом месте программы, экземпляр класса LoginManager:login_manager = LoginManager()Класс LoginManager содержит код, который позволяет организовать нюансы работы приложения совместно с этим расширением. Например: как загружать данные пользователя по его ID, куда отправлять пользователей когда они пытаются войти или выйти и т.д.
Когда приложение полностью сконфигурировано, необходимо передать его в LoginManager:
login_manager.setup_app(app)
Как строится работа
На каждого пользователя заводится
определённая структура (далее User), в
которой кроме прочих, нужных Вам данных
о пользователе, должен быть уникальный
ID и данные по которым можно авторизовать
пользователя (например логин/пароль).
И Flask-Login
со своей стороны будет требовать от
Вас, во-первых, найти объект User по
соответствующему ID, а во-вторых,
найти и вернуть объект User по переданным
при авторизации данным.
Первое необходимо чтобы
найти объект User уже авторизованного
пользователя, при его последующих
запросах исходя из ID который хранится
в его сессии.
Для этого
необходимо назначить callback-функцию с
помощью декоратора user_loader
которая используется расширением для
загрузки объекта User по его ID:
@login_manager.user_loader def load_user(userid): return User.get(userid)
Входной параметр один - строка unicode
содержащая ID пользователя. Функция
должна возвращать None, если ID не существует.
В противном случае, если все в порядке
и пользователь с там ID существует, нужно
вернуть соответствующий ему объект
User.
Второй случай происходит
на этапе авторизации пользователя,
когда Вы имеете некоторые данные (из
формы авторизации к примеру) и по ним
должны определить, корректны ли они и
существует ли пользователь им
соответствующий. И в этом случае, для
того чтобы Flask-Login
поместил нужный ID в сессию пользователя,
Вы должны передать ему через функцию
login_user
объект User. Так же, через в эту функцию
можно передать параметр remember
со значением True, для
реализации функционала «запомнить
меня» - чтобы сессия
пользователя была восстановлена при
следующем входе, без авторизации.
Следующих
пример демонстрирует вариант авторизации
через логин/пароль. Поиск объекта User
осуществляется в функции get_user(login,
password).
@app.route("/login", methods=["GET", "POST"]) def login(): if request.method == "POST": login = request.form["login"] password = request.form["password"] remember_me = request.form["remember"] # ищем пользователя по логину и паролю # get_user - внутренняя функция, для запроса к БД, например
user = get_user(login, password)
if user:
# если пользователь с тамим логином и паролем существует -
# авторизуем и делаем редирект
login_user(user, remember=remember_me)
return redirect(url_for("index"))
return render_template("login.html")
Ограничение доступа к представлениям
Для ограничения доступа, чтобы к представлению могли обращаться только авторизованные пользователи, используется декоратор login_required. При попытке перейти на URL представления с таким декоратором, неавторизованный пользователь будет отправлен на страницу авторизации.Завершение сеанса
Для того чтобы завершить сеанс
пользователя, существует функция
logout_user,
обратная по смыслу login_user.
После её вызова куки из сессии пользователя
будут удалены и он будет считаться
неавторизованным. Вот пример использования:
@app.route("/logout") @login_required def logout(): logout_user() return redirect(somewhere)
Итог
Таким образом подытожим основные действия которые нужно выполнить для добавления в своё приложение функции авторизации:- Определить механизм хранения и
создать набор пользователей, каждый
из которых будет иметь уникальный ID.
- Написать функцию с декоратором
user_loader
которая будет ставить в
соответствие ID конкретный объект
пользователя.
- Установить декоратор login_required
для представлений которые требуют
авторизации.
- Для авторизации добавить представление,
которое будет вызывать функцию login_user
с объектом пользователя если данные
для авторизации будут верны.
- Добавить представление, для
реализации выхода пользователя, которое
будет вызывать функцию logout_user.