Core (он же Auth)
API Endpoints
Regular Auth
Базовая регистрация и авторизация (email-password).
GET /api/v1/auth/regular/register
Требования:
- клиентское приложение
Описание: Зарегистрироваться в системе.
Корректный запрос к серверу (curl):
Bash | |
---|---|
1 2 3 4 5 6 7 8 |
|
Информация
Для получения заголовков клиентских приложений (те, что X-SWAP-CLIENT-APP-{TOKEN,FLAVOR,STAGE,VERSION}
) вам нужно зарегистрировать клиентское приложение.
Для этого:
-
Переходим в админку, авторизуемся в ней
-
После успешной авторизации переходим во вкладку
Client Applications
и нажимаемCreate New Client Application
. -
Внимательно заполняем все поля согласно параметрам вашего клиентского приложения.
-
Нажимаем кнопку
Save
.
После чего система перебросит нас в таблицу, из которой копируем все поля в соответствующие их названиям заголовки запроса (request headers).
Корректный ответ от сервера (JSON):
JSON | |
---|---|
1 2 3 4 5 6 7 8 |
|
Обратите внимание, при регистрации в системе система автоматически производит авторизацию только что созданного пользоваетеля.
POST /api/v1/auth/regular/login
Требования:
- клиентское приложение
Описание: Войти в систему по используемой связке email/password.
Корректный запрос к серверу (curl):
Bash | |
---|---|
1 2 3 4 5 6 7 8 |
|
Корректный ответ от сервера (JSON):
JSON | |
---|---|
1 2 3 4 5 6 7 8 |
|
Обратите внимание - этот токен сохраняется в cookie на доменном уровне и может переиспользоваться между сервисами. Например, залогинившись в core
, мы можем спокойно продолжать работать с profile
и другими сервисами.
Важно!
Во всех сервисах должен быть установлен одинаковый DJANGO_SECRET_KEY
, в противном случае ключ не удастся расшифровать на других сервисах и авторизация на них не будет работать вообще!
Storage
PUT /api/v1/storage/upload
Требования:
- авторизованный пользователь
- клиентское приложение
Описание: Загрузить несколько файлов в файловое хранилище системы SWAP.
Прикрепляем любое количество файлов, важно, чтобы их порядок соответствовал порядку метаданных, переданных в виде JSON Array.
На сервере присутствует валидация, которая не пропускает подозрительные файлы и недопустимые типы.
Список допустимых типов файлов:
- Документы: PDF
- Изображения: JPG/JPEG/PNG
Корректный запрос к серверу (curl):
Bash | |
---|---|
1 2 3 4 5 6 |
|
Корректный ответ от сервера (JSON):
JSON | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
Любые другие ответы считаются некорректными.
GET /api/v1/storage/download/{asset_type}/{asset_id}
Загрузить конкретный файл ассета типа {asset_type}
по идентификатору {asset_id}
.
Напрямую скачивает файл с файлового хранилища в виде бинарного файла.
Корректный запрос к серверу (curl):
Bash | |
---|---|
1 |
|
Корректный ответ от сервера: Успешно загруженный на локальную машину файл с сервера.
Дополнительно
Клиентское приглашение и клиентские сессии
О процессе регистрации (пошагово, поймёт даже тибетский ёж!)
-
Компания-наниматель создаёт приглашения в систему SWAP работникам или сотрудникам компании, например, в админке. Или сразу батчем1 на несколько сотен эмэйлов работников.
Интересный факт
Это похоже на систему регистрации старого Хабрахабра, где регистрация была изначально по инвайтам и зарегистрированный пользователь (в нашем случае - компания) могла пригласить другого пользователя (в нашем случае - работника/или сотрудника компании) на портал. Когда регистрация на Хабре открылась для всех, по факту всех стал "приглашать" один пользователь - НЛО (сделано это было таким образом, чтобы не переделывать существующую логику регистрации). В нашем случае - компания - SWAP Administration, которая создаётся дата-миграцией при деплое (аналогично с наполнением датасетов и созданием главного пользователя - swap_admin).
-
При создании приглашения работникам на бэкэнде автоматически регистрируются их временные2 аккаунты (со временным паролем - токеном от приглашения) и они получают письмо на свои почтовые адреса о том, что компания "SWAP Administration" (или другая - инициатор выдачи приглашений пользователям) приглашает вас зарегистрироваться в системе SWAP по уникальной ссылке.
-
Пользователь переходит по этой ссылке (тем самым инициируя вход в систему под временным паролем)
https://dev.goswap.app/invite/?token=bmSGyXxOrtXlhVY_ceRpzQGnlC4vfj5bvMkcl8eTpf0
Внутри себя фронт вызывает проверку этого токена:
HTTP 1
POST core.dev.goswap.app/api/v1/client-invitations/verify-token/bmSGyXxOrtXlhVY_ceRpzQGnlC4vfj5bvMkcl8eTpf0
И если токен валиден, проверка возвращает ему email пользователя в пэйлоуде. Дальше фронт логинит пользователя.
HTTP 1 2
POST core.dev.goswap.app/api/v1/auth/regular/login {"email": "[email protected]", "password": "bmSGyXxOrtXlhVY_ceRpzQGnlC4vfj5bvMkcl8eTpf0"}
И помещает вернувшиеся
access_token
иverify_token
из пэйлоуда в cookies после успешного входа в систему.Фронты, внимание!
Вы выполняете этот запрос по загрузке урла из email. Проще говоря - пользователь должен быть уже залогинен в свой временный аккаунт, когда зайдёт на экран с установкой пароля. Иначе пароль не сменится!
POST core.dev.goswap.app/api/v1/auth/regular/password/change
работает только для активного (то есть залогинившегося) пользователя!Вопрос: а может ли залогинить пользователя бэк и вернуть хидеры авторизации в verify token?
Ответ: Фактически это будет неправильным поведением с точки зрения логики верификации. Верификация - не производит авторизацию, она проверяет только факт валидности токена. Аутентификация и верификация - априори два разных процесса, имеющих абсолютно разную логику.
-
Авторизовавшись (бесшовно для фронта), пользователь попадает на страницу создания нового пароля (экран 1.0). Ему остаётся только поменять временный пароль на свой и установить дату рождения, ФИО и т.д. Это два запроса:
- Смена пароля
HTTP 1 2
POST core.dev.goswap.app/api/v1/auth/regular/password/change/ {"new_password1": "<new_password>", "new_password2": "<new_password>"}
- Обновление данных аккаунта
HTTP 1 2
PATCH core.dev.goswap.app/api/v1/auth/regular/user/ {... updated fields of GET core.dev.goswap.app/api/v1/auth/regular/user/ response payload ...}
Однако фронтам стоит учесть, что созданный аккаунт временный (вы получите эту инфу в результате выполнения запроса POST core.dev.goswap.app/api/v1/auth/regular/login/
в поле "is_verified": false
объекта user
) и после запроса на сохранение данных запросить ещё отправку верификационного email, выполнив следующий запрос:
HTTP | |
---|---|
1 2 |
|
О клиентских сессиях
Клиентская сессия - это все данные, которые мы сохраняем с разных формочек на клиенте и которые будут использованы для синхронизации между устройствами.
Сейчас объясню на примере.
Условно, начал работник заполнение профиля в телефоне, затем понял, что некоторые документы у него только на компе и решил перейти на комп. И чтобы ему не вводить всё по новой - мы сохраняем состояние его клиентской сессии в БД. Затем, когда он переходит за комп, и авторизуется в системе - мы находим открытую его сессию на телефоне с данными форм и переносим их на комп. После чего сессию на телефоне мы можем закрыть или оставить. Любые изменения в формах на фронте влекут за собой вызов следующего запроса:
HTTP | |
---|---|
1 2 |
|
Фронты, внимание!
Этот запрос полностью меняет содержимое полей (не prepend, а замена!), поэтому вы должны отправлять мне ВСЕ поля, включая неизменённые. Возможно в дальнейшем я поправлю эту логику, когда пойму, как лучше сделать.
Как это всё работает (диаграмма)
flowchart TD
%% nodes description
node_start((start))
node_end((end))
step1["
Компания создаёт приглашение (в бэкофисе или джанговской админке сервиса core) для конкретного пользователя по его email.
При создании приглашения автоматически генерируется пригласительная ссылка,
вида <a href='#'>https://dev.goswap.app/invite/?token=GBg6QtXM_w4ORw5ZzE5k2ErmH7yJGrOqhHT6E5bHGvE</a>
и пользователю автоматически создаётся (если не был создан) аккаунт на бэкэнде по его email со временным паролем.
"]
step2["
По этой ссылке осуществляется переход на фронтэнд.
"]
step3["
На фронтэнде проверяется валидность токена <code>GBg6QtXM_w4ORw5ZzE5k2ErmH7yJGrOqhHT6E5bHGvE</code>
посредством отправки на бэкэнд запроса POST <a href='#'>https://core.dev.goswap.app/api/v1/client-invitations/verify-token/GBg6QtXM_w4ORw5ZzE5k2ErmH7yJGrOqhHT6E5bHGvE</a>
"]
step4{"Токен валидный (т.е. существует и не просрочен?)"}
step5["404 Not Found (если не существует) или 410 Gone (если просрочен)"]
step6["
Фронтэнд генерирует Id сессии и отправляет на бэкэнд POST запрос для открытия новой сессии (не забывая прикрепить хидеры клиентского приложения).
POST <a href="">https://core.dev.goswap.app/api/v1/client-sessions/{session_id}</a>
"]
step7["
Когда сессия открылась, фронтэнд забирает <code>session_id</code> из вернувшегося пэйлоуда и использует его для авторизации сессии либо
в header <code>X-SWAP-CLIENT-SESSION-ID</code>, либо в cookie <code>swap_client_session_id</code>
"]
step8["
Проверить состояние сессии можно в любой момент по запросу
GET <a href>https://core.dev.goswap.app/api/v1/client-sessions/{session_id}</a>
(не забываем прикрепить хидеры клиентского приложения)
Если сессия просрочилась - вернётся 410 Gone.
Если сессии с таким <code>session_id</code> не существует - вернётся 404 Not found.
В противном случае вернётся следующая детализация сессии:
{'id': '3f087e5f-3e07-4d31-a625-8fc1d1d597c3', 'expired_at': '2025-08-01T08:03:36.850059Z', 'created_at': '2025-07-31T08:03:36.850059Z', 'updated_at': '2025-07-31T08:03:36.850079Z', 'session_id': 'aSjrlYnFhsWrOeE1y0d38VyZsq47nzFddOWWfq2HPic', 'token': 'DfIsocWnQrZAHT65cJmIpZoWvH_k7hJyTBCICFDhWro', 'time_to_live': 86400}
"]
%% flowchart
node_start --> step1
step1 --> step2
step2 --> step3
step3 --> step4
step4 --> |Нет| step5
step4 --> |Да| step6
step5 --> step1
step6 --> step7
step7 --> step8
step8 --> node_end
-
то есть выслать множество приглашений одним запросом на множество emails сразу, например
↩HTTP 1 2 3 4 5 6
POST core.dev.goswap.app/api/v1/client-invitations/batch { "invited_by_company": "{company_uuid}", "invited_workers_emails": ["[email protected]", "[email protected]", ..., "[email protected]"], "invited_employee_emails": ["[email protected]", "[email protected]", ..., "[email protected]"] }
-
временные - потому что все неверифицированные аккаунты чистятся определённой таской в кронтабе, условно - раз в неделю ↩