В предыдущих разделах мы рассмотрели, как подключить наше приложение FastAPI к базе данных PostgreSQL и добавили асинхронные запросы. Однако приложение нашего интернет магазина по-прежнему позволяет любому пользователю добавлять категории, товары, а не только пользователям, прошедшим авторизацию.
Методы аутентификации в FastAPI
В FastAPI доступно несколько методов аутентификации. FastAPI поддерживает распространенные методы аутентификации: базовую HTTP-аутентификацию и аутентификацию на основе токенов. Давайте кратко рассмотрим, что влечет за собой каждый метод:
- Базовая HTTP-аутентификация: В этом методе аутентификации учетные данные пользователя, которые обычно представляют собой имя пользователя и пароль, отправляются через HTTP-заголовок авторизации. Запрос, в свою очередь, возвращает заголовок WWW-Authenticate содержащий, базовое значение и необязательный параметр области, который указывает ресурс, к которому выполняется запрос аутентификации.
- Аутентификацию на основе токенов: Этот метод аутентификации включает использование токенов безопасности. Наиболее часто используемым токеном является JWT, который обычно представляет собой словарь, содержащий идентификатор пользователя и срок действия токена.
Каждый из перечисленных здесь методов аутентификации имеет свои конкретные варианты использования, а также свои плюсы и минусы.
В этом разделе мы защитим наше приложение с помощью встроенного класса HTTPBasic и сможем ограничить некоторые операции только для аутентифицированных пользователей. Аутентификация — это процесс проверки учетных данных, переданных объектом, а авторизация просто означает предоставление объекту разрешения на выполнение определенных действий. После проверки учетных данных объект получает право выполнять различные действия.
Создание User модели
Первым делом мы создадим файл models/user.py в котором мы будем хранить модель пользователей:
from app.backend.db import Base
from sqlalchemy import Column, Integer, String, Boolean
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True, index=True)
first_name = Column(String)
last_name = Column(String)
username = Column(String, unique=True)
email = Column(String, unique=True)
hashed_password = Column(String)
is_active = Column(Boolean, default=True)
is_admin = Column(Boolean, default=False)
is_supplier = Column(Boolean, default=False)
is_customer = Column(Boolean, default=True)
Разберем поля этой модели подробнее:
-
id- Поле первичного ключа модели. -
first_name- Поле имени пользователя. -
last_name- Поле фамилии пользователя. -
username- Поле логина пользователя. -
email- Поле E-Mail пользователя -
hashed_password- Поле хранения хэшированного пароля. Хранить не хэшированный пароль не безопасно, поэтому мы будем хранить только его хэш. -
is_active- Поле хранящее булево значение, значениеFalseбудет использоваться в случае удаления пользователя, чтобы заблокировать доступ к некоторым разделам API. По умолчанию используется значениеTrue. -
is_admin- Поле хранящее булево значение, значениеTrueбудет использоваться только для администратора, чтобы предоставить доступ к некоторым разделам API. По умолчанию значениеFalse. -
is_supplier- Поле хранящее булево значение, значениеTrueбудет использоваться только для продавцов товара, чтобы предоставить доступ к некоторым разделам API, например как добавление товара. По умолчанию значениеFalse. -
is_customer- Поле хранящее булево значение, значениеTrueбудет использоваться только для покупателей товара. По умолчанию значениеTrue.
Также добавим в модель товаров поле supplier_id, которое будет создавать связь товара и пользователя, для этого в файле models/products.py внесем следующее изменение:
class Product(Base):
__tablename__ = 'products'
id = Column(Integer, primary_key=True, index=True)
name = Column(String)
slug = Column(String, unique=True, index=True)
description = Column(String)
price = Column(Integer)
image_url = Column(String)
stock = Column(Integer)
supplier_id = Column(Integer, ForeignKey('users.id'), nullable=True) # New
category_id = Column(Integer, ForeignKey('categories.id'))
rating = Column(Float)
is_active = Column(Boolean, default=True)
category = relationship('Category', back_populates='products')
Мы добавили поле supplier_id, использующее отношение многие к одному, чтобы закрепить за каждым товаром своего пользователя(продавца).
Продолжим разработку системы пользователей в следующем шаге.
Первым делом мы создадим файл
model/user.pyВозможно
models/user.py