POST /api/v1/auth/oauth/google
Autentificare prin Google pentru clienți mobili (iOS / Android).
Aplicația mobilă obține id_token prin Google SDK și îl trimite backend-ului. Nu există redirecționări OAuth — verificare stateless prin Google tokeninfo.
Cerere
POST /api/v1/auth/oauth/google
Content-Type: application/json
{
"id_token": "<Google id_token din SDK-ul mobil>"
}
| Câmp | Tip | Obligatoriu | Descriere |
|---|---|---|---|
id_token | string | Da | JWT emis de Google Sign-In SDK pe dispozitiv |
Răspuns 200 — Utilizator existent
{
"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"
}
}
Răspuns 201 — Utilizator nou creat
Același corp, status HTTP 201 Created.
Răspuns 401 — Token invalid
{
"success": false,
"status": "401",
"message": "Invalid Google token",
"errors": null,
"data": null
}
Logica de asociere a contului
| Scenariu | Rezultat |
|---|---|
OAuthIdentity există pentru provider+uid | Autentificare ca utilizatorul asociat |
Nu există identity, dar există User cu acel email | Se creează OAuthIdentity, asociat la User existent |
Nu există identity, nu există User cu acel email | Se creează User nou (rol client) + OAuthIdentity |
Utilizatorii noi din OAuth:
- Primesc o parolă aleatorie (32 hex) — schimbare prin resetarea parolei
- Primesc un telefon placeholder (
placeholder_<hex>) — actualizare prin profil
Verificarea token-ului
Backend-ul apelează Google tokeninfo:
GET https://oauth2.googleapis.com/tokeninfo?id_token=<id_token>
Câmpuri extrase din răspuns:
| Câmp | Utilizare |
|---|---|
sub | UID unic Google |
email | Găsire / creare User |
given_name | Profile.first_name |
family_name | Profile.last_name |
Tabelul oauth_identities
| Coloană | Tip | Descriere |
|---|---|---|
id | UUID (PK) | |
user_id | UUID (FK) | → users.id |
provider | string | "google" (extensibil) |
uid | string | Google sub |
created_at | timestamp | |
updated_at | timestamp |
Index unic: provider + uid. Nu se stochează coloane cu token-uri.