Тестовое задание: бэкенд блога на FastAPI с аутентификацией, ролями и CRUD для постов и категорий.
-
Аутентификация и роли
- Регистрация: email + пароль (bcrypt)
- Логин: выдача access/refresh JWT
- Роли:
USER
(по умолчанию),ADMIN
- Доступ к админ-роутам — только
ADMIN
- Refresh токены — обновление access-токена
-
Санитизация HTML
- Используется bleach
- Разрешённые теги:
p
,br
,strong
,em
,ul
,ol
,li
,a
,h1..h4
,blockquote
,code
,pre
- Разрешённые атрибуты:
href
,title
,alt
- Все данные в
content_html
проходят очистку
-
API
- Публичные:
GET /api/v1/posts
— список постовGET /api/v1/posts/{slug}
— детальноGET /api/v1/categories
— список категорийGET /api/v1/categories/{slug}/posts
— посты категории
- Аутентификация:
POST /api/v1/auth/register
POST /api/v1/auth/login
POST /api/v1/auth/refresh
GET /api/v1/users/me
- Админские:
- CRUD для постов и категорий
- Управление ролями пользователей
- Публичные:
git clone https://github.com/kolofas/FastAPI_Blog_Backend.git
cd FastAPI_Blog_Backend
Создать .env в корне проекта на основе .env.example:
cp .env.example .env
Пример .env.example:
DB_URL=postgresql+psycopg://blog_user:blog_pass@localhost:5432/blog DB_ECHO=False
AUTH_SECRET=change_me_super_secret_key AUTH_ACCESS_TTL_MINUTES=30 AUTH_REFRESH_TTL_DAYS=7 AUTH_ISSUER=fastapi-blog
docker compose up --build
Сервисы: Swagger UI: http://localhost:8000/docs
Зарегистрируйте первого пользователя:
curl -X POST http://localhost:8000/api/v1/auth/register \
-H "Content-Type: application/json" \
-d '{"email":"admin@example.com","password":"Secret123!"}'
docker compose exec db psql -U blog_user -d blog \
-c "UPDATE users SET role='ADMIN' WHERE email='admin@example.com';"
Логин
curl -sS -X POST http://localhost:8000/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"admin@example.com","password":"Secret123!"}'
Получить свои данные
curl -sS http://localhost:8000/api/v1/users/me \
-H "Authorization: Bearer <ACCESS_TOKEN>"
Создать категорию
curl -sS -X POST http://localhost:8000/api/v1/categories \
-H "Authorization: Bearer <ACCESS_TOKEN>" \
-H "Content-Type: application/json" \
-d '{"title":"Футбол"}'
Создать пост
curl -sS -X POST http://localhost:8000/api/v1/posts \
-H "Authorization: Bearer <ACCESS_TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"title":"Матч дня",
"content_html":"<p>Гол на 90+5</p>",
"category_slug":"futbol",
"is_published": true
}'
Обновить пост
curl -sS -X PUT http://localhost:8000/api/v1/posts/match-dnia \
-H "Authorization: Bearer <ACCESS_TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"title":"Обновленный пост",
"content_html":"<p>Updated content</p>",
"is_published": false
}'
Удалить пост
curl -i -sS -X DELETE http://localhost:8000/api/v1/posts/obnovlennyi-post \
-H "Authorization: Bearer <ACCESS_TOKEN>"