flask Лекция

Урок 9: Регистрация, авторизация и Flask-Login

Введение в Web-разработку на Flask: Урок 9

Проблема: Проходной двор

Посмотрите на наш сайт. Сейчас он похож на дом с открытыми настежь дверями.

  • Любой человек может зайти и прочитать посты.
  • Любой может написать глупость.
  • И самое страшное: любой шутник может нажать “Удалить” и стереть чужую работу.

Нам нужна охрана. Нам нужна система Регистрации и Входа.

Цель урока

Научить сайт узнавать пользователей в лицо и раздавать права доступа.


Часть 1: Аутентификация vs Авторизация

Схема отличий аутентификации от авторизации в веб-приложениях

В безопасности есть два похожих слова, которые нужно различать.

Сегодня мы реализуем и то, и другое.


Часть 2: Безопасность паролей (Мясорубка)

Аналогия хеширования паролей: мясорубка, процесс который нельзя повернуть вспять

Главное правило веб-разработчика

НИКОГДА. НЕ ХРАНИТЕ. ПАРОЛИ. В ОТКРЫТОМ ВИДЕ. Если хакер украдет вашу базу данных, он увидит пароли всех пользователей (“12345”, “qwerty”) и взломает их почты.

Решение: Хеширование Мы превращаем пароль в Хеш — набор случайных символов.

  • Пароль: cat123
  • Хеш: pbkdf2:sha256:50$...f9a1

Аналогия: Мясорубка Вы можете прокрутить мясо и получить фарш. Но вы не можете прокрутить фарш назад и получить стейк. При входе на сайт мы берем пароль пользователя, снова крутим через “мясорубку” и сравниваем полученный фарш (хеш) с тем, что лежит в базе.


Часть 3: Инструменты (Flask-Login)

Нам не нужно писать систему входа с нуля. Мы используем библиотеку Flask-Login.

Она берет на себя самую сложную работу:

  1. Session Management: Запоминает пользователя, чтобы ему не приходилось вводить пароль на каждой странице.
  2. UserMixin: Добавляет пользователю нужные свойства (активен ли он, вошел ли в систему).
  3. Current User: Дает нам переменную, в которой всегда лежит “тот, кто сейчас смотрит сайт”.

Часть 4: Модель User

Мы создаем новую таблицу в базе данных.

# UserMixin нужен, чтобы Flask-Login "понимал" этот класс
class User(db.Model, UserMixin):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(50), unique=True) # Имена не должны повторяться
    password_hash = db.Column(db.String(128)) # Храним ТОЛЬКО хеш

    # Функция для установки пароля
    def set_password(self, password):
        self.password_hash = generate_password_hash(password)

    # Функция проверки пароля
    def check_password(self, password):
        return check_password_hash(self.password_hash, password)

Часть 5: Регистрация и Вход

Весь процесс сводится к двум маршрутам.


Часть 6: Защита (Фейс-контроль)

Механизм защиты маршрутов во Flask с помощью декоратора login_required

Теперь мы можем повесить “замок” на любые функции. Декоратор @login_required работает как охранник.

from flask_login import login_required

@app.route("/create", methods=["POST"])
@login_required  # <--- СТОП! Без билета нельзя.
def create_post():
    # Этот код сработает, только если пользователь вошел.
    # Если нет — его перекинет на страницу входа.
    ...

Мы защищаем маршруты создания, редактирования и удаления. Читать посты можно всем.


Часть 7: Интерфейс (Jinja2)

Меню сайта должно меняться.

  • Гость видит: “Войти”, “Регистрация”.
  • Пользователь видит: “Привет, Вася”, “Выйти”.
{% if current_user.is_authenticated %}
    <p>Привет, {{ current_user.username }}</p>
    <a href="/logout">Выйти</a>
{% else %}
    <a href="/login">Войти</a>
{% endif %}

Переменная current_user доступна во всех шаблонах автоматически.


Итоги и Домашнее задание

Резюме урока:

  1. Хеширование: Храним не пароли, а их “отпечатки”.
  2. Flask-Login: Управляет сессиями пользователей.
  3. @login_required: Защищает маршруты от посторонних.
  4. current_user: Позволяет адаптировать верстку под пользователя.

ДЗ: Приватный клуб

  1. Добавьте на сайт систему регистрации и авторизации.
  2. Запретите незарегистрированным пользователям создавать и удалять посты.
  3. Сделайте так, чтобы кнопка “Создать пост” была видна только тем, кто вошел на сайт.

Проверь себя!

В чем главное концептуальное отличие Аутентификации от Авторизации?

Что делает декоратор @login_required перед функцией маршрута?