Процесс онбординга работника (для фронтов)
Шаг 1. Регистрация
- Компания-наниматель создаёт приглашения в систему SWAP работникам или сотрудникам компании, например, в админке. Или сразу батчем1 на несколько сотен эмэйлов работников.
Интересный факт
Это похоже на систему регистрации старого Хабрахабра, где регистрация была изначально по инвайтам и зарегистрированный пользователь (в нашем случае - компания) могла пригласить другого пользователя (в нашем случае - работника/или сотрудника компании) на портал. Когда регистрация на Хабре открылась для всех, по факту всех стал "приглашать" один пользователь - НЛО (сделано это было таким образом, чтобы не переделывать существующую логику регистрации). В нашем случае - компания - SWAP Administration, которая создаётся дата-миграцией при деплое (аналогично с наполнением датасетов и созданием главного пользователя - swap_admin).
Создать приглашение можно следующими способами:
Создать приглашение (админка)
Переходим по ссылке https://api.dev.goswap.app/admin/authentication/clientinvitation/add/ и заполняем требуемые поля.
Нажимаем на кнопку SAVE
Создать приглашение (API)
Чтобы создать приглашение из API, нужно выполнить следующий запрос:
HTTP | |
---|---|
1 2 3 4 5 6 7 8 |
|
- При создании приглашения работникам на бэкэнде автоматически регистрируются их временные2 аккаунты (со временным паролем - токеном от приглашения) и они получают письмо на свои почтовые адреса о том, что компания "SWAP Administration" (или другая - инициатор выдачи приглашений пользователям) приглашает вас зарегистрироваться в системе SWAP по уникальной ссылке.
Вот как это письмо выглядит (персональные данные замазаны):
-
Пользователь переходит по этой ссылке (или qrcode, который представляет эту же ссылку) из письма, тем самым инициируя вход в систему под временным паролем.
Внутри себя фронтэнд:
Сначала вызывает проверку этого токена:
HTTP 1
POST api.dev.goswap.app/v1/client-invitations/verify-token/EJSrRlo2oHPeT4ynSRsAR7n1uzqZnPUqTKn9Z2SIU74
И если токен валиден, проверка возвращает ему email пользователя в пэйлоуде.
Дальше фронт логинит пользователя с данными, которые пришли ему при переходе по ссылке в письме.
Где
email
- query param 'email', аpassword
- query param 'token'.HTTP 1 2
POST api.dev.goswap.app/v1/auth/regular/login {"email": "[email protected]", "password": "EJSrRlo2oHPeT4ynSRsAR7n1uzqZnPUqTKn9Z2SIU74"}
И помещает вернувшиеся
access_token
иverify_token
из пэйлоуда в cookies после успешного входа в систему.Фронты, внимание!
Вы выполняете этот запрос когда пользователь переходит по ссылке или qrcode из email на сайт. Проще говоря - пользователь должен быть уже залогинен в свой временный аккаунт, когда зайдёт на экран с установкой пароля. Иначе пароль не сменится!
POST api.dev.goswap.app/v1/auth/regular/password/change
работает только для активного (то есть залогинившегося) пользователя!Вопрос: а может ли залогинить пользователя бэк и вернуть хидеры авторизации в verify token?
Ответ: Фактически это будет неправильным поведением с точки зрения логики верификации. Верификация - не производит авторизацию, она проверяет только факт валидности токена. Аутентификация и верификация - априори два разных процесса, имеющих абсолютно разную логику.
-
Авторизовавшись (бесшовно для фронта), пользователь попадает на страницу создания нового пароля (экран 1.0). Ему остаётся только поменять временный пароль на свой и установить дату рождения, ФИО и т.д. Это два запроса:
- Смена пароля
HTTP 1 2
POST api.dev.goswap.app/v1/auth/regular/password/change/ {"new_password1": "<new_password>", "new_password2": "<new_password>"}
- Обновление базовых данных аккаунта уже авторизованного пользователя
HTTP 1 2 3 4 5 6
PATCH api.dev.goswap.app/v1/auth/regular/user/ { "username": "loremsupernickname", "full_name": "Lorem Ipsum", "birth_date": "1968-01-08" }
Однако фронтам стоит учесть, что созданный аккаунт временный (вы получите эту инфу в результате выполнения запроса POST core.dev.goswap.app/api/v1/auth/regular/login/
в поле "is_verified": false
объекта user
) и после запроса на сохранение данных запросить ещё отправку верификационного email, выполнив следующий запрос:
HTTP | |
---|---|
1 2 |
|
Шаг 2. Создание (открытие) клиентской сессии
Клиентская сессия - это все данные, которые мы сохраняем с разных формочек на клиенте и которые будут использованы для синхронизации между устройствами.
Сейчас объясню на примере.
Условно, начал работник заполнение профиля в телефоне, затем понял, что некоторые документы у него только на компе и решил перейти на комп. И чтобы ему не вводить всё по новой - мы сохраняем состояние его клиентской сессии в БД. Затем, когда он переходит за комп, и авторизуется в системе - мы находим открытую его сессию на телефоне с данными форм и переносим их на комп. После чего сессию на телефоне мы можем закрыть или оставить. Любые изменения в формах на фронте влекут за собой вызов следующего запроса:
HTTP | |
---|---|
1 2 |
|
Фронты, внимание!
Этот запрос полностью меняет содержимое полей (не prepend, а замена!), поэтому вы должны отправлять мне ВСЕ поля, включая неизменённые. Возможно в дальнейшем я поправлю эту логику, когда пойму, как лучше сделать.
Для создания (открытия) клиентской сессии в первую очередь нужно сгенерировать session_id.
Сгенерировать {session_id}
нужно на фронтэнде, например, вот таким способом:
JavaScript | |
---|---|
1 |
|
Допустим, эта команда сгенерировала нам следующий Session ID: i4mch15iicbvhhrhpx1bohv1zvvzeidulmi
Для открытия клиентской сессии на бэкэнде нужно выполнить следующий POST запрос (не забывая прикрепить хидеры клиентского приложения):
Bash | |
---|---|
1 2 3 4 5 6 7 8 |
|
Данные для хидеров можно посмотреть здесь: https://api.dev.goswap.app/admin/authentication/clientapplication/
Для фронтэнда берём Web, для мобильных устройств Mobile.
В ответ вернётся подобный response:
Text Only | |
---|---|
1 2 3 4 5 6 7 8 9 |
|
Шаг 3. Заполнение данных профиля работника
Создаём профиль работника. В фигме это экран 1.1 на странице worker - тот, что слева от этого экрана. Прямая ссылка на него: https://www.figma.com/design/GTSngpLtUDwLxAwGL4aa7D/mobile-SWAP?node-id=2973-264941&t=AmUMGyctblFuX4VY-4
HTTP | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 |
|
Как это всё работает (диаграмма)
flowchart TD
%% nodes description
node_start((start))
node_end((end))
step1["
Компания создаёт приглашение (в бэкофисе или джанговской админке сервиса core) для конкретного пользователя по его email (например [email protected]).
При создании приглашения автоматически генерируется пригласительная ссылка,
вида <a href='#'>https://dev.goswap.app/invite/?token=EJSrRlo2oHPeT4ynSRsAR7n1uzqZnPUqTKn9Z2SIU74&[email protected]&role=WORKER</a>
и пользователю автоматически создаётся (если не был создан) аккаунт на бэкэнде по его email со временным паролем.
"]
step2["
По этой ссылке осуществляется переход на фронтэнд.
"]
step3["
На фронтэнде проверяется валидность токена <code>EJSrRlo2oHPeT4ynSRsAR7n1uzqZnPUqTKn9Z2SIU74</code>
посредством отправки на бэкэнд запроса POST <a href='#'>https://api.dev.goswap.app/v1/client-invitations/verify-token/EJSrRlo2oHPeT4ynSRsAR7n1uzqZnPUqTKn9Z2SIU74</a>
"]
step4{"Токен валидный (т.е. существует и не просрочен?)"}
step5["404 Not Found (если не существует) или 410 Gone (если просрочен)"]
step6["
Фронтэнд генерирует Id сессии и отправляет на бэкэнд POST запрос для открытия новой сессии (не забывая прикрепить хидеры клиентского приложения).
POST <a href="">https://api.dev.goswap.app/v1/auth/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://api.dev.goswap.app/v1/auth/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 7 8
POST api.dev.goswap.app/v1/auth/client-invitations/batch { "invited_by_company": "{company_uuid}", "invitations": [ {"email": "[email protected]", "role": "WORKER"}, {"email": "[email protected]", "role": "COMPANY_MANAGER", "prefilled_fields": {"title": "C1 Company"}} ] }
-
временные - потому что все неверифицированные аккаунты чистятся определённой таской в кронтабе, условно - раз в неделю ↩