POST /api/v1/auth/oauth/google
Sign-in через Google для мобильных клиентов (iOS / Android).
Мобильное приложение получает id_token через Google SDK и отправляет его на бэкенд. OAuth-редиректов нет — верификация stateless через Google tokeninfo.
Запрос
POST /api/v1/auth/oauth/google
Content-Type: application/json
{
"id_token": "<Google id_token из мобильного SDK>"
}
| Поле | Тип | Обязательно | Описание |
|---|---|---|---|
id_token | string | Да | JWT, выданный Google Sign-In SDK на устройстве |
Ответ 200 — Существующий пользователь
{
"success": true,
"status": "200",
"message": "Signed in with Google",
"errors": null,
"data": {
"access_token": "<jwt>",
"refresh_token": "<jwt>",
"expires_at": "2026-04-06T12:30:00Z"
}
}
Ответ 201 — Новый пользователь создан
Тело то же, HTTP статус 201 Created.
Ответ 401 — Невалидный токен
{
"success": false,
"status": "401",
"message": "Invalid Google token",
"errors": null,
"data": null
}
Логика привязки аккаунта
| Сценарий | Результат |
|---|---|
OAuthIdentity существует для provider+uid | Вход как привязанный пользователь |
Нет identity, но User с таким email есть | Создать OAuthIdentity, привязать к существующему User |
Нет identity, нет User с таким email | Создать нового User (роль client) + OAuthIdentity |
Новые пользователи из OAuth:
- Получают случайный пароль (32 hex) — смена через сброс пароля
- Получают placeholder-телефон (
placeholder_<hex>) — обновить через профиль
Верификация токена
Бэкенд вызывает Google tokeninfo:
GET https://oauth2.googleapis.com/tokeninfo?id_token=<id_token>
Из ответа используются:
| Поле | Применение |
|---|---|
sub | Уникальный Google uid |
email | Поиск / создание User |
given_name | Profile.first_name |
family_name | Profile.last_name |
Таблица oauth_identities
| Колонка | Тип | Описание |
|---|---|---|
id | UUID (PK) | |
user_id | UUID (FK) | → users.id |
provider | string | "google" (расширяемо) |
uid | string | Google sub |
created_at | timestamp | |
updated_at | timestamp |
Уникальный индекс: provider + uid. Колонок с токенами нет.