Поиск по сайту:

Как добавить аутентификацию в ваше приложение с помощью Flask-Login


Введение

Разрешение пользователям входить в ваше приложение — одна из наиболее распространенных функций, которые вы добавите в свои веб-приложения. Вы можете добавить аутентификацию в свое приложение Flask с помощью пакета Flask-Login.

В этом уроке вы:

  • Используйте библиотеку Flask-Login для управления сеансом.
  • Используйте встроенную утилиту Flask для хеширования паролей
  • Добавить защищенные страницы в приложение только для зарегистрированных пользователей
  • Используйте Flask-SQLAlchemy для создания модели User
  • Создайте формы регистрации и входа, чтобы пользователи могли создавать учетные записи и входить в систему.
  • Сообщения об ошибках возвращаются пользователям, когда что-то идет не так.
  • Использовать информацию из аккаунта пользователя для отображения на странице профиля.

Вы создадите страницу регистрации и входа, которые позволят пользователям входить в систему и получать доступ к защищенным страницам. Вы будете использовать информацию из модели User и отображать ее на защищенных страницах, когда пользователь входит в систему, чтобы имитировать внешний вид профиля.

Примечание. Это руководство имеет ограниченный объем и не охватывает расширенное сохранение сеансов. Кроме того, изменение типа данных для первичного ключа или соображения по переходу на другие системы баз данных также выходят за рамки этого вводного руководства.

Исходный код этого проекта доступен на GitHub.

Предпосылки

Для выполнения этого урока вам потребуется следующее:

  • Некоторое знакомство с Python.
  • Python установлен в локальной среде.
  • Знание основ навигации и управления файлами в Linux.

Вот диаграмма, которая дает представление о том, как будет выглядеть файловая структура проекта после завершения обучения:

.
└── flask_auth_app
    └── project
        ├── __init__.py       # setup the app
        ├── auth.py           # the auth routes for the app
        ├── db.sqlite         # the database
        ├── main.py           # the non-auth routes for the app
        ├── models.py         # the user model
        └── templates
            ├── base.html     # contains common layout and links
            ├── index.html    # show the home page
            ├── login.html    # show the login form
            ├── profile.html  # show the profile page
            └── signup.html   # show the signup form

По мере прохождения руководства вы создадите эти каталоги и файлы.

Это руководство было проверено с помощью sqlite3 v3.36.0, python v3.9.8, flask v2.0.2, flask-login v0.5.0 и flask-sqlachemy v2.5.1.

Шаг 1 — Установка пакетов

Для вашего проекта вам понадобятся три основных пакета:

  • Фласк
  • Flask-Login: для обработки пользовательских сеансов после аутентификации
  • Flask-SQLAlchemy: для представления пользовательской модели и интерфейса с базой данных

Вы будете использовать SQLite, чтобы избежать установки каких-либо дополнительных зависимостей для базы данных.

Во-первых, начните с создания каталога проекта:

  1. mkdir flask_auth_app

Затем перейдите в каталог проекта:

  1. cd flask_auth_app

Вы захотите создать среду Python, если у вас ее нет.

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

В зависимости от того, как Python был установлен на вашем компьютере, ваша команда будет выглядеть примерно так:

  1. python3 -m venv auth

Флаг -m предназначен для имя-модуля. Эта команда выполнит модуль venv для создания новой виртуальной среды с именем auth. Это создаст новый каталог, содержащий подкаталоги bin, include и lib. И файл pyvenv.cfg.

Затем выполните следующую команду:

  1. source auth/bin/activate

Эта команда активирует виртуальную среду.

Запустите следующую команду из виртуальной среды, чтобы установить необходимые пакеты:

  1. pip install flask flask-sqlalchemy flask-login

Теперь, когда вы установили пакеты, вы готовы создать основной файл приложения.

Шаг 2 — Создание основного файла приложения

Начнем с создания каталога project:

  1. mkdir project

Первым файлом будет файл __init__.py для проекта:

  1. nano project/__init__.py

Это приложение будет использовать шаблон фабрики приложений Flask с чертежами. Один план обрабатывает обычные маршруты, включая индекс и защищенную страницу профиля. Другой план обрабатывает все, что связано с авторизацией. В реальном приложении вы можете разбить функциональность по своему усмотрению, но описанное здесь решение хорошо подойдет для этого руководства.

Этот файл будет иметь функцию для создания приложения, которое будет инициализировать базу данных и регистрировать чертежи. На данный момент это мало что даст, но понадобится для остальной части приложения.

Вам нужно будет инициализировать SQLAlchemy, установить некоторые значения конфигурации и зарегистрировать схемы здесь:

from flask import Flask
from flask_sqlalchemy import SQLAlchemy

# init SQLAlchemy so we can use it later in our models
db = SQLAlchemy()

def create_app():
    app = Flask(__name__)

    app.config['SECRET_KEY'] = 'secret-key-goes-here'
    app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///db.sqlite'

    db.init_app(app)

    # blueprint for auth routes in our app
    from .auth import auth as auth_blueprint
    app.register_blueprint(auth_blueprint)

    # blueprint for non-auth parts of app
    from .main import main as main_blueprint
    app.register_blueprint(main_blueprint)

    return app

Теперь, когда у вас есть основной файл приложения, начните добавлять маршруты.

Шаг 3 — Добавление маршрутов

Для маршрутов вы будете использовать два чертежа.

Для main_blueprint у вас будет домашняя страница (/) и страница профиля (/profile).

Сначала создайте main.py:

  1. nano project/main.py

Затем добавьте свой main_blueprint:

from flask import Blueprint
from . import db

main = Blueprint('main', __name__)

@main.route('/')
def index():
    return 'Index'

@main.route('/profile')
def profile():
    return 'Profile'

Для auth_blueprint у вас будут маршруты для получения как страницы входа (/login), так и страницы регистрации (/signup). Наконец, у вас будет маршрут выхода (/logout) для выхода активного пользователя.

Затем создайте auth.py:

  1. nano project/auth.py

Затем добавьте свой auth_blueprint:

from flask import Blueprint
from . import db

auth = Blueprint('auth', __name__)

@auth.route('/login')
def login():
    return 'Login'

@auth.route('/signup')
def signup():
    return 'Signup'

@auth.route('/logout')
def logout():
    return 'Logout'

А пока определите login, signup и logout с возвратом текста. У вас также будут маршруты для обработки запросов POST от login и signup. Вы вернетесь к этому коду позже и дополните его желаемой функциональностью.

В терминале вы можете установить значения FLASK_APP и FLASK_DEBUG:

  1. export FLASK_APP=project
  2. export FLASK_DEBUG=1

Переменная среды FLASK_APP указывает Flask, как загрузить приложение. Вы бы хотели, чтобы это указывало на то, где находится create_app. В этом руководстве вы будете указывать на каталог project.

Переменная среды FLASK_DEBUG активируется, если установить для нее значение 1. Это включит отладчик, который будет отображать ошибки приложения в браузере.

Убедитесь, что вы находитесь в каталоге flask_auth_app, а затем запустите проект:

  1. flask run

Теперь в веб-браузере вы можете перейти к пяти возможным URL-адресам и увидеть возвращенный текст, определенный в auth.py и main.py.

Например, при посещении localhost:5000/profile отображается: Profile:

Убедившись, что маршруты ведут себя должным образом, можно создавать шаблоны.

Шаг 4 — Создание шаблонов

Затем создайте шаблоны, которые используются в приложении. Это первый шаг перед тем, как вы сможете реализовать фактическую функциональность входа в систему.

Приложение будет использовать четыре шаблона:

  • index.html
  • profile.html
  • логин.html
  • signup.html

У вас также будет базовый шаблон с кодом, общим для каждой из страниц. В этом случае базовый шаблон будет иметь навигационные ссылки и общий макет страницы.

Сначала создайте каталог templates в каталоге project:

  1. mkdir -p project/templates

Затем создайте base.html:

  1. nano project/templates/base.html

Затем добавьте следующий код в файл base.html:

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Flask Auth Example</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.2/css/bulma.min.css" />
</head>

<body>
    <section class="hero is-primary is-fullheight">

        <div class="hero-head">
            <nav class="navbar">
                <div class="container">
                    <div id="navbarMenuHeroA" class="navbar-menu">
                        <div class="navbar-end">
                            <a href="{{ url_for('main.index') }}" class="navbar-item">
                                Home
                            </a>
                            <a href="{{ url_for('main.profile') }}" class="navbar-item">
                                Profile
                            </a>
                            <a href="{{ url_for('auth.login') }}" class="navbar-item">
                                Login
                            </a>
                            <a href="{{ url_for('auth.signup') }}" class="navbar-item">
                                Sign Up
                            </a>
                            <a href="{{ url_for('auth.logout') }}" class="navbar-item">
                                Logout
                            </a>
                        </div>
                    </div>
                </div>
            </nav>
        </div>

        <div class="hero-body">
            <div class="container has-text-centered">
               {% block content %}
               {% endblock %}
            </div>
        </div>
    </section>
</body>

</html>

Этот код создаст серию ссылок меню на каждую страницу приложения. Он также устанавливает блок для content, который может быть перезаписан дочерними шаблонами.

Примечание. В этом руководстве используется официальная документация Bulma.

Затем создайте templates/index.html:

  1. nano project/templates/index.html

Добавьте следующий код во вновь созданный файл, чтобы добавить содержимое на страницу:

{% extends "base.html" %}

{% block content %}
<h1 class="title">
  Flask Login Example
</h1>
<h2 class="subtitle">
  Easy authentication and authorization in Flask.
</h2>
{% endblock %}

Этот код создаст базовую индексную страницу с заголовком и подзаголовком.

Затем создайте templates/login.html:

  1. nano project/templates/login.html

Этот код создает страницу входа с полями для электронной почты и пароля. Также есть флажок, чтобы «запомнить» сеанс, в котором вы вошли в систему.

{% extends "base.html" %}

{% block content %}
<div class="column is-4 is-offset-4">
    <h3 class="title">Login</h3>
    <div class="box">
        <form method="POST" action="/login">
            <div class="field">
                <div class="control">
                    <input class="input is-large" type="email" name="email" placeholder="Your Email" autofocus="">
                </div>
            </div>

            <div class="field">
                <div class="control">
                    <input class="input is-large" type="password" name="password" placeholder="Your Password">
                </div>
            </div>
            <div class="field">
                <label class="checkbox">
                    <input type="checkbox" name="remember">
                    Remember me
                </label>
            </div>
            <button class="button is-block is-info is-large is-fullwidth">Login</button>
        </form>
    </div>
</div>
{% endblock %}

Затем создайте templates/signup.html:

  1. nano project/templates/signup.html

Добавьте следующий код, чтобы создать страницу регистрации с полями для email, name и password:

{% extends "base.html" %}

{% block content %}
<div class="column is-4 is-offset-4">
    <h3 class="title">Sign Up</h3>
    <div class="box">
        <form method="POST" action="/signup">
            <div class="field">
                <div class="control">
                    <input class="input is-large" type="email" name="email" placeholder="Email" autofocus="">
                </div>
            </div>

            <div class="field">
                <div class="control">
                    <input class="input is-large" type="text" name="name" placeholder="Name" autofocus="">
                </div>
            </div>

            <div class="field">
                <div class="control">
                    <input class="input is-large" type="password" name="password" placeholder="Password">
                </div>
            </div>

            <button class="button is-block is-info is-large is-fullwidth">Sign Up</button>
        </form>
    </div>
</div>
{% endblock %}

Затем создайте templates/profile.html:

  1. nano project/templates/profile.html

Добавьте этот код, чтобы создать страницу с заголовком, который жестко закодирован для приветствия Энтони:

{% extends "base.html" %}

{% block content %}
<h1 class="title">
  Welcome, Anthony!
</h1>
{% endblock %}

Вы вернетесь к этому коду позже, чтобы динамически приветствовать любого пользователя.

После того, как вы добавили шаблоны, вы можете обновить операторы возврата в каждом из маршрутов, чтобы возвращать шаблоны вместо текста.

Затем обновите main.py, изменив строку импорта и маршруты для index и profile:

from flask import Blueprint, render_template
...
@main.route('/')
def index():
    return render_template('index.html')

@main.route('/profile')
def profile():
    return render_template('profile.html')

Теперь вы обновите auth.py, изменив строку импорта и маршруты для login и signup:

from flask import Blueprint, render_template
...
@auth.route('/login')
def login():
    return render_template('login.html')

@auth.route('/signup')
def signup():
    return render_template('signup.html')

После внесения этих изменений вот как будет выглядеть страница регистрации, если вы перейдете к /signup:

Вы также можете перейти на страницы /, /login и /profile.

Пока оставьте /logout без изменений, потому что позже он не будет отображать шаблон.

Шаг 5 — Создание пользовательских моделей

Модель пользователя представляет, что означает для приложения наличие пользователя. В этом руководстве потребуются поля для адреса электронной почты, пароля и имени. В будущих приложениях вы можете решить, что хотите хранить гораздо больше информации для каждого пользователя. Вы можете добавить такие вещи, как дни рождения, изображения профиля, местоположения или любые пользовательские настройки.

Модели, созданные в Flask-SQLAlchemy, представлены классами, которые затем преобразуются в таблицы в базе данных. Затем атрибуты этих классов превращаются в столбцы для этих таблиц.

Создайте модель User:

  1. nano project/models.py

Определите модель User:

from . import db

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True) # primary keys are required by SQLAlchemy
    email = db.Column(db.String(100), unique=True)
    password = db.Column(db.String(100))
    name = db.Column(db.String(1000))

Этот код определяет Пользователя со столбцами для id, электронной почты, пароля и имени.

Теперь, когда вы создали модель User, вы можете перейти к настройке базы данных.

Шаг 6 — Настройка базы данных

Вы будете использовать базу данных SQLite. Вы можете создать базу данных SQLite самостоятельно, но пусть Flask-SQLAlchemy сделает это за вас. У вас уже есть путь к базе данных, указанный в файле __init__.py, поэтому вам нужно указать Flask-SQLAlchemy создать базу данных в Python REPL.

Убедитесь, что вы все еще находитесь в виртуальной среде и в каталоге flask_auth_app.

Если вы остановите приложение и откроете Python REPL, вы сможете создать базу данных с помощью метода create_all объекта db:

  1. from project import db, create_app, models
  2. db.create_all(app=create_app()) # pass the create_app result so Flask-SQLAlchemy gets the configuration.

Примечание. Если вы впервые используете интерпретатор Python, вы можете обратиться к официальной документации.

Теперь вы увидите файл db.sqlite в каталоге вашего проекта. В этой базе данных будет пользовательская таблица.

Шаг 7 — Настройка функции авторизации

Для функции регистрации вы берете данные, которые пользователь отправляет в форму, и добавляете их в базу данных. Вам нужно будет убедиться, что пользователь с таким же адресом электронной почты еще не существует в базе данных. Если он не существует, вам нужно убедиться, что вы хэшируете пароль, прежде чем помещать его в базу данных.

Примечание. Хранение паролей в открытом виде считается плохой практикой безопасности. Как правило, вам понадобится сложный алгоритм хеширования и соль для обеспечения безопасности паролей.

Начнем с добавления второй функции для обработки данных формы POST. Соберите данные, переданные от пользователя.

Обновите auth.py, изменив строку импорта и реализовав signup_post:

from flask import Blueprint, render_template, redirect, url_for
...
@auth.route('/signup')
def signup():
    return render_template('signup.html')

@auth.route('/signup', methods=['POST'])
def signup_post():
    # code to validate and add user to database goes here
    return redirect(url_for('auth.login'))

Создайте функцию и добавьте перенаправление. Это обеспечит пользовательский опыт успешной регистрации и перенаправления на страницу входа.

Теперь давайте добавим остальную часть кода, необходимого для регистрации пользователя. Используйте объект запроса, чтобы получить данные формы.

Продолжайте обновлять auth.py, добавляя импорт и реализуя signup_post:

from flask import Blueprint, render_template, redirect, url_for, request
from werkzeug.security import generate_password_hash, check_password_hash
from .models import User
from . import db
...
@auth.route('/signup', methods=['POST'])
def signup_post():
    # code to validate and add user to database goes here
    email = request.form.get('email')
    name = request.form.get('name')
    password = request.form.get('password')

    user = User.query.filter_by(email=email).first() # if this returns a user, then the email already exists in database

    if user: # if a user is found, we want to redirect back to signup page so user can try again
        return redirect(url_for('auth.signup'))

    # create a new user with the form data. Hash the password so the plaintext version isn't saved.
    new_user = User(email=email, name=name, password=generate_password_hash(password, method='sha256'))

    # add the new user to the database
    db.session.add(new_user)
    db.session.commit()

    return redirect(url_for('auth.login'))

Этот код проверит, существует ли пользователь с таким же адресом электронной почты в базе данных.

Шаг 8 — Тестирование метода регистрации

Теперь, когда вы завершили процедуру регистрации, вы сможете создать нового пользователя. Давайте протестируем форму для создания пользователя.

Проверить успешность регистрации можно двумя способами:

  • Вы можете использовать средство просмотра базы данных, чтобы просмотреть строку, которая была добавлена в вашу таблицу.
  • Или вы можете попробовать зарегистрироваться с тем же адресом электронной почты еще раз, и если вы получите сообщение об ошибке, вы будете знать, что первое письмо было сохранено правильно.

Давайте добавим код, чтобы сообщить пользователю, что электронная почта уже существует, и направить его на страницу входа. Вызвав функцию flash, вы можете отправить сообщение на следующий запрос, которым в данном случае является перенаправление. Страница, на которую перенаправляется пользователь, будет иметь доступ к этому сообщению в шаблоне.

Во-первых, добавьте flash перед перенаправлением на страницу регистрации.

from flask import Blueprint, render_template, redirect, url_for, request, flash
...
@auth.route('/signup', methods=['POST'])
def signup_post():
    ...
    if user: # if a user is found, we want to redirect back to signup page so user can try again
        flash('Email address already exists')
        return redirect(url_for('auth.signup'))

Чтобы получить в шаблоне всплывающее сообщение, вы можете добавить этот код перед формой.

...
{% with messages = get_flashed_messages() %}
{% if messages %}
    <div class="notification is-danger">
        {{ messages[0] }}. Go to <a href="{{ url_for('auth.login') }}">login page</a>.
    </div>
{% endif %}
{% endwith %}
<form method="POST" action="/signup">

Этот код отобразит сообщение Адрес электронной почты уже существует. Перейдите на страницу входа., если адрес электронной почты уже есть в базе данных.

На этом этапе вы можете запустить приложение и попытаться зарегистрироваться с уже существующим адресом электронной почты.

Шаг 9 — Добавление метода входа

Метод входа аналогичен функции регистрации. В этом случае вы сравните введенный адрес email, чтобы увидеть, есть ли он в базе данных. Если это так, вы проверите пароль, предоставленный пользователем, путем хеширования пароля, который передает пользователь, и сравнения его с хешированным паролем в базе данных. . Вы узнаете, что пользователь ввел правильный пароль, когда оба хешированных пароля совпадают.

Как только пользователь пройдет проверку пароля, вы узнаете, что у него правильные учетные данные, и вы сможете войти в систему с помощью Flask-Login. Вызвав login_user, Flask-Login создаст сеанс для этого пользователя, который будет сохраняться, пока пользователь остается в системе, что позволит пользователю просматривать защищенные страницы.

Вы можете начать с нового маршрута для обработки данных, отправленных с помощью POST. И перенаправить на страницу профиля, когда пользователь успешно войдет в систему:

...
@auth.route('/login')
def login():
    return render_template('login.html')

@auth.route('/login', methods=['POST'])
def login_post():
    # login code goes here
    return redirect(url_for('main.profile'))

Теперь вам нужно проверить, есть ли у пользователя правильные учетные данные:

...
@auth.route('/login', methods=['POST'])
def login_post():
    # login code goes here
    email = request.form.get('email')
    password = request.form.get('password')
    remember = True if request.form.get('remember') else False

    user = User.query.filter_by(email=email).first()

    # check if the user actually exists
    # take the user-supplied password, hash it, and compare it to the hashed password in the database
    if not user or not check_password_hash(user.password, password):
        flash('Please check your login details and try again.')
        return redirect(url_for('auth.login')) # if the user doesn't exist or password is wrong, reload the page

    # if the above check passes, then we know the user has the right credentials
    return redirect(url_for('main.profile'))

Давайте добавим блок в шаблон, чтобы пользователь мог видеть мигающее сообщение:

...
{% with messages = get_flashed_messages() %}
{% if messages %}
    <div class="notification is-danger">
        {{ messages[0] }}
    </div>
{% endif %}
{% endwith %}
<form method="POST" action="/login">

Теперь у вас есть возможность сказать, что пользователь успешно вошел в систему, но ему не во что войти.

Flask-Login может управлять сеансами пользователей. Начните с добавления UserMixin в вашу модель User. UserMixin добавит в модель атрибуты Flask-Login, чтобы Flask-Login мог с ней работать.

from flask_login import UserMixin
from . import db

class User(UserMixin, db.Model):
    id = db.Column(db.Integer, primary_key=True) # primary keys are required by SQLAlchemy
    email = db.Column(db.String(100), unique=True)
    password = db.Column(db.String(100))
    name = db.Column(db.String(1000))

Затем вам нужно указать загрузчик пользователя. Загрузчик пользователей сообщает Flask-Login, как найти конкретного пользователя по идентификатору, который хранится в его файле cookie сеанса. Добавьте это в функцию create_app вместе с кодом init для Flask-Login:

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_login import LoginManager
...
def create_app():
    ...
    db.init_app(app)

    login_manager = LoginManager()
    login_manager.login_view = 'auth.login'
    login_manager.init_app(app)

    from .models import User

    @login_manager.user_loader
    def load_user(user_id):
        # since the user_id is just the primary key of our user table, use it in the query for the user
        return User.query.get(int(user_id))

Наконец, добавьте функцию login_user перед перенаправлением на страницу профиля для создания сеанса:

from flask_login import login_user
from .models import User
from . import db
...
@auth.route('/login', methods=['POST'])
def login_post():
    ...
    # if the above check passes, then we know the user has the right credentials
    login_user(user, remember=remember)
    return redirect(url_for('main.profile'))

При настройке Flask-Login используйте маршрут /login. Когда все будет на месте, вы увидите страницу профиля.

На этом этапе вы можете запустить приложение и попытаться войти в систему.

Шаг 10 — Защита страниц

Если ваше имя не Энтони, то вы увидите, что ваше имя неверно на странице профиля. Цель состоит в том, чтобы профиль отображал имя в базе данных. Вам нужно будет защитить страницу, а затем получить доступ к данным пользователя, чтобы получить имя.

Чтобы защитить страницу при использовании Flask-Login, добавьте декоратор @login_required между маршрутом и функцией. Это предотвратит просмотр маршрута пользователем, не вошедшим в систему. Если пользователь не вошел в систему, он будет перенаправлен на страницу входа в соответствии с конфигурацией Flask-Login.

С маршрутами, украшенными декоратором @login_required, вы можете использовать объект current_user внутри функции. Этот current_user представляет пользователя из базы данных и обеспечивает доступ ко всем атрибутам этого пользователя с помощью точечной нотации. Например, current_user.email, current_user.password и current_user.name и current_user.id вернут фактические значения, хранящиеся в базе данных для вошедшего в систему пользователя.

Давайте воспользуемся name current_user и отправим его в шаблон:

from flask import Blueprint, render_template
from flask_login import login_required, current_user
from . import db
...
@main.route('/profile')
@login_required
def profile():
    return render_template('profile.html', name=current_user.name)

Затем в файле profile.html обновите страницу, чтобы отобразить значение name:

...
<h1 class="title">
  Welcome, {{ name }}!
</h1>

Как только пользователь заходит на страницу профиля, его приветствует его имя.

Теперь, чтобы обновить представление выхода, вызовите функцию logout_user в маршруте для выхода:

from flask_login import login_user, login_required, logout_user
...
@auth.route('/logout')
@login_required
def logout():
    logout_user()
    return redirect(url_for('main.index'))

Используйте декоратор @login_required, потому что не имеет смысла выходить из системы пользователя, который не вошел в систему с самого начала.

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

Это связано с тем, что Flask-Login выдает сообщение, когда пользователю не разрешен доступ к странице.

И последнее, что нужно сделать, это добавить операторы if в шаблоны, чтобы отображались только те ссылки, которые имеют отношение к пользователю:

...
<div class="navbar-end">
    <a href="{{ url_for('main.index') }}" class="navbar-item">
        Home
    </a>
    {% if current_user.is_authenticated %}
    <a href="{{ url_for('main.profile') }}" class="navbar-item">
        Profile
    </a>
    {% endif %}
    {% if not current_user.is_authenticated %}
    <a href="{{ url_for('auth.login') }}" class="navbar-item">
        Login
    </a>
    <a href="{{ url_for('auth.signup') }}" class="navbar-item">
        Sign Up
    </a>
    {% endif %}
    {% if current_user.is_authenticated %}
    <a href="{{ url_for('auth.logout') }}" class="navbar-item">
        Logout
    </a>
    {% endif %}
</div>

Прежде чем пользователь войдет в систему, у него будет возможность войти или зарегистрироваться. После того, как они вошли в систему, они могут перейти в свой профиль или выйти из системы.

Таким образом, вы успешно создали свое приложение с аутентификацией.

Заключение

В этом руководстве вы использовали Flask-Login и Flask-SQLAlchemy для создания системы входа в приложение. Вы рассказали, как аутентифицировать пользователя, сначала создав модель пользователя и сохранив информацию о пользователе. Затем вам нужно было проверить правильность пароля пользователя, хешировав пароль из формы и сравнив его с паролем, хранящимся в базе данных. Наконец, вы добавили авторизацию в приложение с помощью декоратора @login_required на странице профиля, чтобы эту страницу могли видеть только вошедшие в систему пользователи.

Того, что вы создали в этом руководстве, будет достаточно для небольших приложений, но если вы хотите иметь больше функциональности с самого начала, вы можете рассмотреть возможность использования библиотек Flask-User или Flask-Security, которые созданы поверх библиотеки Библиотека Flask-Login.