123 lines
2.6 KiB
Markdown
123 lines
2.6 KiB
Markdown
# Google Auth - Backend
|
|
|
|
## Endpoint
|
|
|
|
```
|
|
POST /v1/auth/google-login
|
|
```
|
|
|
|
### Request
|
|
|
|
```json
|
|
{
|
|
"credential": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."
|
|
}
|
|
```
|
|
|
|
### Response (200)
|
|
|
|
```json
|
|
{
|
|
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
|
|
"token_type": "bearer",
|
|
"user": {
|
|
"id": "uuid",
|
|
"email": "user@gmail.com",
|
|
"username": "user",
|
|
"tenant_id": null,
|
|
"status": "ACTIVE",
|
|
"created_at": "...",
|
|
"profile": {
|
|
"full_name": "User Name",
|
|
"phone": null,
|
|
"timezone": "Asia/Jakarta"
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
### Error Responses
|
|
|
|
| Status | Detail |
|
|
|--------|--------|
|
|
| 401 | `Kredensial Google tidak valid atau telah kedaluwarsa.` |
|
|
| 401 | `Tidak dapat mengambil email dari akun Google.` |
|
|
|
|
---
|
|
|
|
## Logic
|
|
|
|
1. Verify JWT token dari Google via `google.oauth2.id_token.verify_oauth2_token()` dengan `GOOGLE_CLIENT_ID`
|
|
2. Extract `email` dan `name` dari token payload
|
|
3. Cari user by `email` di database
|
|
4. **Jika user belum ada:**
|
|
- Generate username dari email prefix (jika duplicate, tambah suffix angka: `user`, `user2`, `user3`...)
|
|
- Generate random 32-char password (tidak pernah dipakai)
|
|
- Set `email_verified_at = now` (Google sudah verifikasi)
|
|
- Set `status = ACTIVE`
|
|
- Buat `UserProfile` dengan `full_name` dari Google
|
|
5. **Jika user sudah ada:**
|
|
- Update `email_verified_at` jika belum terisi
|
|
- Update `full_name` jika berubah
|
|
- Create profile jika belum ada
|
|
6. Return JWT access token + user detail
|
|
|
|
---
|
|
|
|
## Schema
|
|
|
|
```python
|
|
class GoogleLoginRequest(BaseModel):
|
|
credential: str
|
|
```
|
|
|
|
---
|
|
|
|
## Config
|
|
|
|
### Environment Variable
|
|
|
|
```env
|
|
# api/.env
|
|
GOOGLE_CLIENT_ID=xxx.apps.googleusercontent.com
|
|
```
|
|
|
|
### Settings
|
|
|
|
```python
|
|
# api/app/config.py
|
|
class Settings(BaseSettings):
|
|
GOOGLE_CLIENT_ID: str = ""
|
|
```
|
|
|
|
---
|
|
|
|
## Dependencies
|
|
|
|
```
|
|
google-auth==2.56.2
|
|
```
|
|
|
|
Ditambahkan ke `api/requirements.txt`.
|
|
|
|
---
|
|
|
|
## Files Changed
|
|
|
|
| File | Change |
|
|
|------|--------|
|
|
| `api/app/config.py` | Tambah `GOOGLE_CLIENT_ID: str = ""` |
|
|
| `api/.env` | Tambah `GOOGLE_CLIENT_ID=xxx` |
|
|
| `api/app/schemas/user.py` | Tambah `GoogleLoginRequest` schema |
|
|
| `api/app/routers/auth.py` | Tambah endpoint `POST /v1/auth/google-login` + imports |
|
|
| `api/requirements.txt` | Tambah `google-auth==2.56.2` |
|
|
|
|
---
|
|
|
|
## Design Decisions
|
|
|
|
- **Tidak pakai kolom `google_id`** - User matching pakai `email` dari Google token, tidak perlu kolom baru di DB
|
|
- **Password field tetap NOT NULL** - Google user dapat random password hash (tidak pernah dipakai)
|
|
- **Auto-verify email** - `email_verified_at` langsung diisi karena Google sudah verifikasi email
|
|
- **Status langsung ACTIVE** - Tidak perlu alur onboarding untuk Google user
|