first commit
This commit is contained in:
449
belgeler/AVATAR_IN_ALL_ENDPOINTS.md
Normal file
449
belgeler/AVATAR_IN_ALL_ENDPOINTS.md
Normal file
@@ -0,0 +1,449 @@
|
||||
# ✅ Avatar Artık Tüm Endpoint'lerde Dönüyor!
|
||||
|
||||
## 🎯 Sorun Çözüldü
|
||||
|
||||
Avatar field'ı login, register ve me endpoint'lerinde dönmüyordu. Şimdi **tüm authentication endpoint'lerinde** avatar döndürülüyor.
|
||||
|
||||
---
|
||||
|
||||
## 📋 Güncellenen Endpoint'ler
|
||||
|
||||
### 1. POST /v1/auth/register ✅
|
||||
|
||||
**Response (201):**
|
||||
```json
|
||||
{
|
||||
"message": "User created. Please verify your email.",
|
||||
"user_id": "uuid",
|
||||
"username": "john_doe",
|
||||
"email": "john@example.com",
|
||||
"avatar": "",
|
||||
"roles": [],
|
||||
"email_verified": false,
|
||||
"verification_token": "token123"
|
||||
}
|
||||
```
|
||||
|
||||
**Not:** Register'da OAuth olmadığı için avatar başlangıçta boş olacak. Daha sonra admin tarafından güncellenebilir.
|
||||
|
||||
---
|
||||
|
||||
### 2. POST /v1/auth/login ✅
|
||||
|
||||
**Response (200):**
|
||||
```json
|
||||
{
|
||||
"user_id": "uuid",
|
||||
"username": "john_doe",
|
||||
"email": "john@example.com",
|
||||
"avatar": "https://lh3.googleusercontent.com/a/...",
|
||||
"roles": [
|
||||
{
|
||||
"id": "role-uuid",
|
||||
"name": "user",
|
||||
"description": "Default user role"
|
||||
}
|
||||
],
|
||||
"access_token": "eyJhbGci...",
|
||||
"refresh_token": "eyJhbGci..."
|
||||
}
|
||||
```
|
||||
|
||||
**Not:** Eğer kullanıcı daha önce OAuth ile giriş yaptıysa, avatar URL'si döner.
|
||||
|
||||
---
|
||||
|
||||
### 3. GET /v1/auth/me ✅
|
||||
|
||||
**Response (200):**
|
||||
```json
|
||||
{
|
||||
"id": "uuid",
|
||||
"username": "john_doe",
|
||||
"email": "john@example.com",
|
||||
"avatar": "https://lh3.googleusercontent.com/a/...",
|
||||
"email_verified": true,
|
||||
"created_at": "2026-02-04T00:00:00Z",
|
||||
"updated_at": "2026-02-04T00:00:00Z",
|
||||
"roles": [
|
||||
{
|
||||
"id": "role-uuid",
|
||||
"name": "user"
|
||||
}
|
||||
],
|
||||
"social_accounts": [
|
||||
{
|
||||
"provider": "google",
|
||||
"name": "John Doe",
|
||||
"avatar_url": "https://lh3.googleusercontent.com/a/..."
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**Not:** Me endpoint'i zaten user objesini döndürüyordu, bu yüzden avatar otomatik olarak eklendi.
|
||||
|
||||
---
|
||||
|
||||
### 4. GET /v1/auth/:provider/callback ✅ YENİ!
|
||||
|
||||
**Response (200):**
|
||||
```json
|
||||
{
|
||||
"access_token": "eyJhbGci...",
|
||||
"refresh_token": "eyJhbGci...",
|
||||
"user": {
|
||||
"id": "uuid",
|
||||
"username": "John Doe",
|
||||
"email": "john@gmail.com",
|
||||
"avatar": "https://lh3.googleusercontent.com/a/...",
|
||||
"email_verified": true,
|
||||
"roles": [
|
||||
{
|
||||
"id": "role-uuid",
|
||||
"name": "user"
|
||||
}
|
||||
],
|
||||
"social_accounts": [
|
||||
{
|
||||
"id": "social-uuid",
|
||||
"provider": "google",
|
||||
"provider_id": "1234567890",
|
||||
"email": "john@gmail.com",
|
||||
"name": "John Doe",
|
||||
"avatar_url": "https://lh3.googleusercontent.com/a/...",
|
||||
"created_at": "2026-02-04T00:00:00Z"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Not:** OAuth callback artık user bilgilerini de döndürüyor, avatar dahil!
|
||||
|
||||
---
|
||||
|
||||
## 🔄 Değişiklikler
|
||||
|
||||
### 1. Auth Handler - Register
|
||||
```go
|
||||
c.JSON(http.StatusCreated, gin.H{
|
||||
"message": "User created. Please verify your email.",
|
||||
"user_id": user.ID,
|
||||
"username": user.UserName,
|
||||
"email": user.Email,
|
||||
"avatar": user.Avatar, // ✅ Eklendi
|
||||
"roles": roles,
|
||||
"email_verified": false,
|
||||
"verification_token": verifyToken,
|
||||
})
|
||||
```
|
||||
|
||||
### 2. Auth Handler - Login
|
||||
```go
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"user_id": user.ID,
|
||||
"username": user.UserName,
|
||||
"email": user.Email,
|
||||
"avatar": user.Avatar, // ✅ Eklendi
|
||||
"roles": roles,
|
||||
"access_token": accessToken,
|
||||
"refresh_token": refreshToken,
|
||||
})
|
||||
```
|
||||
|
||||
### 3. Auth Service - FindOrCreateSocialUser
|
||||
```go
|
||||
// Return type değişti
|
||||
func FindOrCreateSocialUser(gothUser goth.User, provider string) (*models.User, string, string, error)
|
||||
|
||||
// User objesini de döndürüyor
|
||||
return &user, accessToken, refreshToken, nil
|
||||
```
|
||||
|
||||
### 4. Auth Handler - OAuth Callback
|
||||
```go
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"access_token": accessToken,
|
||||
"refresh_token": refreshToken,
|
||||
"user": gin.H{ // ✅ User bilgileri eklendi
|
||||
"id": user.ID,
|
||||
"username": user.UserName,
|
||||
"email": user.Email,
|
||||
"avatar": user.Avatar, // ✅ Avatar dahil
|
||||
"email_verified": user.EmailVerified,
|
||||
"roles": roles,
|
||||
"social_accounts": user.SocialAccounts,
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🧪 Test Senaryoları
|
||||
|
||||
### Test 1: Email/Password ile Register
|
||||
```bash
|
||||
curl -X POST http://localhost:8080/v1/auth/register \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"username": "testuser",
|
||||
"email": "test@example.com",
|
||||
"password": "Test123!"
|
||||
}'
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"message": "User created. Please verify your email.",
|
||||
"username": "testuser",
|
||||
"email": "test@example.com",
|
||||
"avatar": "", // ✅ Boş string
|
||||
"email_verified": false
|
||||
}
|
||||
```
|
||||
|
||||
### Test 2: Email/Password ile Login
|
||||
```bash
|
||||
curl -X POST http://localhost:8080/v1/auth/login \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"email": "test@example.com",
|
||||
"password": "Test123!"
|
||||
}'
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"username": "testuser",
|
||||
"email": "test@example.com",
|
||||
"avatar": "", // ✅ Eğer OAuth kullanmadıysa boş
|
||||
"access_token": "...",
|
||||
"refresh_token": "..."
|
||||
}
|
||||
```
|
||||
|
||||
### Test 3: Google OAuth ile Giriş
|
||||
```bash
|
||||
# 1. OAuth başlat
|
||||
open http://localhost:8080/v1/auth/google
|
||||
|
||||
# 2. Google'da izin ver
|
||||
|
||||
# 3. Callback response
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"access_token": "...",
|
||||
"refresh_token": "...",
|
||||
"user": {
|
||||
"username": "John Doe",
|
||||
"email": "john@gmail.com",
|
||||
"avatar": "https://lh3.googleusercontent.com/a/...", // ✅ Google avatar
|
||||
"email_verified": true,
|
||||
"social_accounts": [
|
||||
{
|
||||
"provider": "google",
|
||||
"name": "John Doe",
|
||||
"avatar_url": "https://lh3.googleusercontent.com/a/..."
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Test 4: /me Endpoint
|
||||
```bash
|
||||
curl -X GET http://localhost:8080/v1/auth/me \
|
||||
-H "Authorization: Bearer YOUR_TOKEN"
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"id": "uuid",
|
||||
"username": "John Doe",
|
||||
"email": "john@gmail.com",
|
||||
"avatar": "https://lh3.googleusercontent.com/a/...", // ✅ Avatar var
|
||||
"email_verified": true
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 💻 Frontend Kullanımı
|
||||
|
||||
### Login Sonrası
|
||||
```javascript
|
||||
async function login(email, password) {
|
||||
const response = await fetch('http://localhost:8080/v1/auth/login', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ email, password })
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
// Avatar artık login response'unda!
|
||||
console.log('Avatar:', data.avatar);
|
||||
|
||||
// Token'ları sakla
|
||||
localStorage.setItem('access_token', data.access_token);
|
||||
localStorage.setItem('refresh_token', data.refresh_token);
|
||||
|
||||
// User bilgilerini sakla
|
||||
localStorage.setItem('user', JSON.stringify({
|
||||
id: data.user_id,
|
||||
username: data.username,
|
||||
email: data.email,
|
||||
avatar: data.avatar // ✅ Avatar
|
||||
}));
|
||||
|
||||
return data;
|
||||
}
|
||||
```
|
||||
|
||||
### OAuth Callback Sonrası
|
||||
```javascript
|
||||
// OAuth callback sayfasında
|
||||
async function handleOAuthCallback() {
|
||||
// URL'den token ve user bilgilerini al
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
|
||||
// veya callback API'sinden direkt response gelir
|
||||
const response = await fetch(callbackUrl);
|
||||
const data = await response.json();
|
||||
|
||||
// Avatar ve tüm user bilgileri var!
|
||||
console.log('User:', data.user);
|
||||
console.log('Avatar:', data.user.avatar);
|
||||
console.log('Social Accounts:', data.user.social_accounts);
|
||||
|
||||
// Token'ları sakla
|
||||
localStorage.setItem('access_token', data.access_token);
|
||||
localStorage.setItem('user', JSON.stringify(data.user));
|
||||
|
||||
// Ana sayfaya yönlendir
|
||||
window.location.href = '/dashboard';
|
||||
}
|
||||
```
|
||||
|
||||
### Me Endpoint ile Avatar Göster
|
||||
```javascript
|
||||
async function getCurrentUser() {
|
||||
const token = localStorage.getItem('access_token');
|
||||
|
||||
const response = await fetch('http://localhost:8080/v1/auth/me', {
|
||||
headers: { 'Authorization': `Bearer ${token}` }
|
||||
});
|
||||
|
||||
const user = await response.json();
|
||||
|
||||
// Avatar göster
|
||||
const avatarEl = document.querySelector('#user-avatar');
|
||||
avatarEl.src = user.avatar || `https://ui-avatars.com/api/?name=${user.username}`;
|
||||
|
||||
return user;
|
||||
}
|
||||
```
|
||||
|
||||
### React Component
|
||||
```jsx
|
||||
function UserProfile() {
|
||||
const [user, setUser] = useState(null);
|
||||
|
||||
useEffect(() => {
|
||||
// Login sonrası user bilgileri localStorage'dan
|
||||
const userData = JSON.parse(localStorage.getItem('user'));
|
||||
setUser(userData);
|
||||
}, []);
|
||||
|
||||
if (!user) return null;
|
||||
|
||||
return (
|
||||
<div className="flex items-center gap-2">
|
||||
<img
|
||||
src={user.avatar || `https://ui-avatars.com/api/?name=${user.username}`}
|
||||
alt={user.username}
|
||||
className="w-10 h-10 rounded-full"
|
||||
/>
|
||||
<span>{user.username}</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📊 Avatar Field Durumları
|
||||
|
||||
| Senaryo | Avatar Değeri |
|
||||
|---------|---------------|
|
||||
| Email/Password Register | `""` (boş string) |
|
||||
| Email/Password Login (OAuth yok) | `""` (boş string) |
|
||||
| Google OAuth ile giriş | `https://lh3.googleusercontent.com/a/...` |
|
||||
| GitHub OAuth ile giriş | `https://avatars.githubusercontent.com/u/...` |
|
||||
| Admin tarafından manuel set | Custom URL |
|
||||
| Avatar hiç set edilmemişse | `null` veya `""` |
|
||||
|
||||
---
|
||||
|
||||
## ✅ Özet
|
||||
|
||||
### Güncellenen Endpoint'ler
|
||||
1. ✅ **POST /v1/auth/register** - Avatar field eklendi
|
||||
2. ✅ **POST /v1/auth/login** - Avatar field eklendi
|
||||
3. ✅ **GET /v1/auth/me** - Avatar zaten vardı (model değişikliği ile)
|
||||
4. ✅ **GET /v1/auth/:provider/callback** - User bilgileri ve avatar eklendi
|
||||
|
||||
### Değişiklikler
|
||||
- ✅ `auth_handler.go` - Register response'a avatar eklendi
|
||||
- ✅ `auth_handler.go` - Login response'a avatar eklendi
|
||||
- ✅ `auth_handler.go` - OAuth callback'e user bilgileri eklendi
|
||||
- ✅ `auth_service.go` - FindOrCreateSocialUser user döndürüyor
|
||||
|
||||
### Avatar Kaynakları
|
||||
- ✅ Google OAuth → Google profil fotoğrafı
|
||||
- ✅ GitHub OAuth → GitHub profil fotoğrafı
|
||||
- ✅ Manuel upload → Custom URL (gelecekte)
|
||||
- ✅ Fallback → UI Avatars API
|
||||
|
||||
### Build
|
||||
```bash
|
||||
✅ go build -o main .
|
||||
✅ No errors
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Hemen Test Edin
|
||||
|
||||
```bash
|
||||
# 1. Uygulamayı başlat
|
||||
./main
|
||||
|
||||
# 2. Register test
|
||||
curl -X POST http://localhost:8080/v1/auth/register \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"username":"test","email":"test@test.com","password":"Test123!"}'
|
||||
|
||||
# Response'da "avatar": "" göreceksiniz ✅
|
||||
|
||||
# 3. Login test
|
||||
curl -X POST http://localhost:8080/v1/auth/login \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"email":"test@test.com","password":"Test123!"}'
|
||||
|
||||
# Response'da "avatar": "" göreceksiniz ✅
|
||||
|
||||
# 4. Google OAuth test
|
||||
open http://localhost:8080/v1/auth/google
|
||||
|
||||
# Callback'te avatar ve tüm user bilgileri olacak ✅
|
||||
```
|
||||
|
||||
**Avatar artık tüm endpoint'lerde dönüyor! 🎉**
|
||||
Reference in New Issue
Block a user