FastAPI – User Registration and Authorization #5

Posted by


FastAPI – Регистрация и Авторизация Пользователей

В этом уроке мы рассмотрим, как реализовать функционал регистрации и аутентификации пользователей с использованием FastAPI, мощного фреймворка для разработки веб-приложений на Python.

Шаг 1: Установка зависимостей
Перед началом работы нам необходимо установить FastAPI и библиотеку PyJWT для работы с JSON Web Tokens. Вы можете установить их, выполнив следующие команды:

pip install fastapi
pip install uvicorn
pip install pyjwt

Шаг 2: Создание схемы для пользователей
Создадим схему, которая будет описывать данные пользователя. Для этого создадим новый файл models.py и добавим следующий код:

from pydantic import BaseModel

class User(BaseModel):
    username: str
    password: str

Шаг 3: Регистрация пользователей
Теперь давайте создадим эндпоинт для регистрации новых пользователей. Создайте новый файл main.py и добавьте следующий код:

from fastapi import FastAPI, HTTPException
from models import User

app = FastAPI()

users_db = []

@app.post("/register/")
async def register(user: User):
    if user.username in [u.username for u in users_db]:
        raise HTTPException(status_code=400, detail="Username already exists")

    users_db.append(user)
    return {"message": "User registered successfully"}

Шаг 4: Аутентификация пользователей
Теперь создадим эндпоинт для аутентификации пользователей. Добавьте следующий код в файл main.py:

import jwt
from fastapi import Depends

SECRET_KEY = "mysecretkey"

@app.post("/login/")
async def login(user: User):
    db_user = next((u for u in users_db if u.username == user.username), None)
    if db_user is None or db_user.password != user.password:
        raise HTTPException(status_code=400, detail="Invalid username or password")

    token = jwt.encode({"username": user.username}, SECRET_KEY)
    return {"access_token": token}

Шаг 5: Защита эндпоинтов
Теперь давайте добавим декоратор, который будет проверять наличие токена аутентификации при доступе к защищенным эндпоинтам. Добавьте следующий код в файл main.py:

from fastapi import HTTPException, Depends
from fastapi.security import OAuth2PasswordBearer

oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/login/")

def get_current_user(token: str = Depends(oauth2_scheme)):
    try:
        payload = jwt.decode(token, SECRET_KEY)
        username = payload.get("username")
        if username is None:
            raise HTTPException(status_code=401, detail="Invalid token")
    except jwt.PyJWTError:
        raise HTTPException(status_code=401, detail="Invalid token")

    return username

@app.get("/protected/")
async def protected_route(username: str = Depends(get_current_user)):
    return {"message": f"Hello, {username}"}

Шаг 6: Запуск приложения
Теперь давайте запустим наше приложение. Выполните следующую команду:

uvicorn main:app --reload

Поздравляем! Теперь у вас есть функционал регистрации и аутентификации пользователей с использованием FastAPI. Удачи в вашем дальнейшем развитии!

0 0 votes
Article Rating
23 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
@artemshumeiko
1 month ago

💡 Попробуй онлайн-тренажёр для подготовки к техническому собеседованию: https://clck.ru/3B5gwP 💡

Забирай роадмап изучения самого востребованного фреймворка на Python – FastAPI здесь: https://t.me/ArtemShumeikoBot

@ellipsis_1337
1 month ago

Большое спасибо за видео,очень полезно.Один момент:
Возможно ли в Swagger doc где эндпоинт login поменять название поля с "username" на "email"
Потому что,вводит в заблуждение разработчика,там по факту поле принимает email,но название username
Спасибо заранее за ответ

@ivanstereotekkofficial5353
1 month ago

Мне очень кажется странным что в реализации этой библиотеки нет модели с refresh_token , хотя копаясь в недрах самой библиотеки я нашел в классе BaseUserManager поле с рефреш токеном. То есть автор полагал что это поле нужное, но в документации эта тема совсем не тронута. И у вас вижу не реализован метод refresh и вы работаете с одним токеном. Может есть объективные причины на это, могли бы сказать почему ?

@EK_7987
1 month ago

кто то сталкивался с такой проблемой ?
ERROR [alembic.util.messaging] Can't locate revision identified by 'ec8057f307c7'

@orthodox-chanel
1 month ago

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

@orthodox-chanel
1 month ago

c 10й попытки заработало и у меня. Все время после регистраици возвращало ошибку сервера крутил все что можно и так и этак пока в конце не снес всю базу и руками не прописал на чистом sql создание таблиц. Видимо рано мне еще алембик или что-то не так…

@vinc2OOO
1 month ago

"detail": "JWTError" в dependencies хотя токены совпадают. В чем может быть дело?

@vinc2OOO
1 month ago

UnicodeDecodeError: 'utf-8' codec can't decode byte 0xc2 in position 61: invalid continuation byte

@user-ix5vl2ry8j
1 month ago

супер! спасибо!! мне понравилось!

@Edvardmoskovka
1 month ago

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

@shalaginovdanila5421
1 month ago

40:40 у меня статус 204

@alexanderfilin7269
1 month ago

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

@dikiykoban2150
1 month ago

хотелось бы больше видео где идёт фулстек разработка, чтобы параллельно всю работу бэкенда одевать в красивый фронтенд

@somebytouchedmyspagget9183
1 month ago

Про JWT токен немного неверно. JWT токен можно спокойно создавать самому, достаточно отследить его в запросах на сервере. И потом уже просто по скрытому API генерировать его, когда он истекает. Сам недавно столкнулся с этим, когда нужно было спарсить один сайт с ключевыми запросами на вб.

@user-ww4bo1vt5i
1 month ago

Предупреждение 
Поскольку наивные объекты datetime рассматриваются многими методами datetime как локальное время, предпочтительнее использовать данные datetimes для представления времени в UTC. Таким образом, рекомендуемый способ создания объекта, представляющего текущее время в UTC, – это вызов datetime.now(timezone.utc) вместо datetime.utcnow.(начиная если не ошибаюсь с 3.10)

@iml404
1 month ago

Эх щас бы велосипеды попридумывать когда есть джанго

@CrozetIs
1 month ago

А где можно подробнее познакомится с сессиями? Не совсем понятно для чего то и зачем

@iJaVolo
1 month ago

Либо я чего-то не понял, либо в видео и правда не показано, как авторизоваться потом. Зарегистрироваться форма сработала. А вот на /jwt/login "LOGIN_BAD_CREDENTIALS" почему-то (там правда кроме username и password ещё 3 поля, может их как-то задействовать надо, хз)

@amalshakov
1 month ago

43:33 Зачем мы создали UNprotected? (Далее им не пользуемся)

@amalshakov
1 month ago

40:32 Я при авторизации созданного пользователя ловлю 204, а не 200. При этом пользователь авторизируется (проверил). В чем тут нюанс?