Files
next-go-blog/USER_PROFILE_API.md
Beyhan Oğur 6d95e27114 first commit
2026-04-26 22:16:43 +03:00

14 KiB
Raw Blame History

Kullanıcı Profil Yönetimi API

Genel Bakış

AuthCentral kullanıcıları kendi profillerini yönetebilir. Bu dokümantasyon kullanıcı profil yönetimi endpoint'lerini açıklar.

Endpoint'ler

1. Profil Bilgilerini Getir

GET /v1/profile

Headers:

  • Authorization: Bearer {access_token}

Yanıt:

{
  "id": "7d8b023c-d5e4-4f62-8811-ddbf00d675bb",
  "username": "admin",
  "email": "admin@gauth.local",
  "avatar": "/uploads/avatars/admin_avatar.png",
  "email_verified": true,
  "is_oauth_user": false,
  "created_at": "2026-02-04T20:00:00Z",
  "updated_at": "2026-02-05T10:00:00Z",
  "roles": [
    {
      "id": 1,
      "name": "admin",
      "description": "Administrator role"
    }
  ],
  "social_accounts": []
}

Yeni Field:

  • is_oauth_user (boolean) - Kullanıcı OAuth ile mi giriş yapmış (Google/GitHub)

Örnek:

TOKEN="your_access_token_here"

curl -X GET "http://localhost:8080/v1/profile" \
  -H "Authorization: Bearer $TOKEN"

2. Profil Güncelle

PUT /v1/profile

Headers:

  • Authorization: Bearer {access_token}
  • Content-Type: multipart/form-data (avatar yüklemek için)

Form Data:

  • user_name (string, optional) - Yeni kullanıcı adı
  • avatar (file, optional) - Profil resmi (max 5MB)

Örnek (Username Güncelleme):

TOKEN="your_access_token_here"

curl -X PUT "http://localhost:8080/v1/profile" \
  -H "Authorization: Bearer $TOKEN" \
  -F "user_name=Beyhan Oğur"

Örnek (Avatar Yükleme):

TOKEN="your_access_token_here"

curl -X PUT "http://localhost:8080/v1/profile" \
  -H "Authorization: Bearer $TOKEN" \
  -F "avatar=@/path/to/profile-picture.jpg"

Örnek (Username + Avatar):

TOKEN="your_access_token_here"

curl -X PUT "http://localhost:8080/v1/profile" \
  -H "Authorization: Bearer $TOKEN" \
  -F "user_name=Beyhan Oğur" \
  -F "avatar=@/path/to/profile-picture.jpg"

Başarılı Yanıt:

{
  "message": "Profile updated successfully",
  "user": {
    "id": "7d8b023c-d5e4-4f62-8811-ddbf00d675bb",
    "username": "Beyhan Oğur",
    "email": "admin@gauth.local",
    "avatar": "/uploads/avatars/7d8b023c_1770238858420987000.png",
    "email_verified": true,
    "roles": [...]
  }
}

3. Şifre Değiştir

PUT /v1/profile/password

Headers:

  • Authorization: Bearer {access_token}
  • Content-Type: application/json

Request Body:

{
  "current_password": "OldPassword123",
  "new_password": "NewPassword123"
}

Örnek:

TOKEN="your_access_token_here"

curl -X PUT "http://localhost:8080/v1/profile/password" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "current_password": "OldPassword123",
    "new_password": "NewPassword123"
  }'

Başarılı Yanıt:

{
  "message": "Password changed successfully"
}

Hata Yanıtları:

{
  "error": "Current password is incorrect"
}
{
  "error": "Cannot change password for OAuth users (Google/GitHub login)"
}

Notlar:

  • Mevcut şifre doğrulanır
  • Yeni şifre minimum 6 karakter olmalı
  • ⚠️ OAuth kullanıcıları (Google/GitHub) şifre değiştiremez
  • ⚠️ Şifre değiştirildikten sonra yeni şifre ile login yapılmalı
  • 💡 is_oauth_user: true ise şifre değiştirme butonu gösterilmemeli

4. Email Adresi Değiştir

PUT /v1/profile/email

Headers:

  • Authorization: Bearer {access_token}
  • Content-Type: application/json

Request Body:

{
  "new_email": "newemail@example.com",
  "password": "YourCurrentPassword"
}

Örnek:

TOKEN="your_access_token_here"

curl -X PUT "http://localhost:8080/v1/profile/email" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "new_email": "newemail@example.com",
    "password": "YourPassword123"
  }'

Başarılı Yanıt:

{
  "message": "Email updated. Please verify your new email address.",
  "new_email": "newemail@example.com",
  "verification_token": "abc123def456..."
}

Hata Yanıtları:

{
  "error": "Password is incorrect"
}
{
  "error": "Email already in use"
}
{
  "error": "Cannot change email for OAuth users (Google/GitHub login)"
}

Önemli Notlar:

  • ⚠️ OAuth kullanıcıları (Google/GitHub) email değiştiremez
  • ⚠️ Email değiştirildiğinde email_verified false olur
  • ⚠️ Yeni email adresine doğrulama email'i gönderilir
  • ⚠️ Email doğrulanana kadar login yapılamaz
  • ⚠️ Email doğrulama için /v1/auth/verify-email?token=... endpoint'i kullanılır
  • 💡 is_oauth_user: true ise email değiştirme butonu gösterilmemeli

Kullanım Senaryoları

Senaryo 1: Tam Profil Güncelleme

#!/bin/bash

# Login
TOKEN=$(curl -s -X POST http://localhost:8080/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email":"user@example.com","password":"password123"}' | jq -r '.access_token')

# 1. Kullanıcı adını güncelle
curl -X PUT "http://localhost:8080/v1/profile" \
  -H "Authorization: Bearer $TOKEN" \
  -F "user_name=Yeni İsim"

# 2. Avatar yükle
curl -X PUT "http://localhost:8080/v1/profile" \
  -H "Authorization: Bearer $TOKEN" \
  -F "avatar=@./my-photo.jpg"

# 3. Şifre değiştir
curl -X PUT "http://localhost:8080/v1/profile/password" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "current_password": "password123",
    "new_password": "newpassword456"
  }'

# 4. Profili kontrol et
curl -X GET "http://localhost:8080/v1/profile" \
  -H "Authorization: Bearer $TOKEN" | jq '.'

Senaryo 2: Email Değiştirme ve Doğrulama

#!/bin/bash

# Login
TOKEN=$(curl -s -X POST http://localhost:8080/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email":"old@example.com","password":"password123"}' | jq -r '.access_token')

# 1. Email değiştir
RESPONSE=$(curl -s -X PUT "http://localhost:8080/v1/profile/email" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "new_email": "new@example.com",
    "password": "password123"
  }')

echo $RESPONSE | jq '.'

# 2. Verification token'ı al
VERIFY_TOKEN=$(echo $RESPONSE | jq -r '.verification_token')

# 3. Email'i doğrula
curl -X GET "http://localhost:8080/v1/auth/verify-email?token=$VERIFY_TOKEN"

# 4. Yeni email ile login
curl -X POST http://localhost:8080/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{
    "email": "new@example.com",
    "password": "password123"
  }'

Frontend Entegrasyonu

React Örneği

import React, { useState, useEffect } from 'react';

function ProfilePage() {
  const [user, setUser] = useState(null);
  const [loading, setLoading] = useState(false);
  const token = localStorage.getItem('access_token');

  // Profil bilgilerini yükle
  const fetchProfile = async () => {
    try {
      const response = await fetch('http://localhost:8080/v1/profile', {
        headers: {
          'Authorization': `Bearer ${token}`
        }
      });
      const data = await response.json();
      setUser(data);
    } catch (error) {
      console.error('Error fetching profile:', error);
    }
  };

  // Username güncelle
  const updateUsername = async (newUsername) => {
    const formData = new FormData();
    formData.append('user_name', newUsername);

    try {
      const response = await fetch('http://localhost:8080/v1/profile', {
        method: 'PUT',
        headers: {
          'Authorization': `Bearer ${token}`
        },
        body: formData
      });
      
      if (response.ok) {
        fetchProfile(); // Profili yenile
        alert('Username updated!');
      }
    } catch (error) {
      console.error('Error updating username:', error);
    }
  };

  // Avatar yükle
  const uploadAvatar = async (file) => {
    const formData = new FormData();
    formData.append('avatar', file);

    try {
      const response = await fetch('http://localhost:8080/v1/profile', {
        method: 'PUT',
        headers: {
          'Authorization': `Bearer ${token}`
        },
        body: formData
      });
      
      if (response.ok) {
        fetchProfile(); // Profili yenile
        alert('Avatar uploaded!');
      }
    } catch (error) {
      console.error('Error uploading avatar:', error);
    }
  };

  // Şifre değiştir
  const changePassword = async (currentPassword, newPassword) => {
    try {
      const response = await fetch('http://localhost:8080/v1/profile/password', {
        method: 'PUT',
        headers: {
          'Authorization': `Bearer ${token}`,
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({
          current_password: currentPassword,
          new_password: newPassword
        })
      });
      
      const data = await response.json();
      
      if (response.ok) {
        alert('Password changed successfully!');
      } else {
        alert(data.error);
      }
    } catch (error) {
      console.error('Error changing password:', error);
    }
  };

  // Email değiştir
  const changeEmail = async (newEmail, password) => {
    try {
      const response = await fetch('http://localhost:8080/v1/profile/email', {
        method: 'PUT',
        headers: {
          'Authorization': `Bearer ${token}`,
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({
          new_email: newEmail,
          password: password
        })
      });
      
      const data = await response.json();
      
      if (response.ok) {
        alert('Email updated! Please check your email to verify.');
      } else {
        alert(data.error);
      }
    } catch (error) {
      console.error('Error changing email:', error);
    }
  };

  useEffect(() => {
    fetchProfile();
  }, []);

  return (
    <div>
      <h1>Profile</h1>
      {user && (
        <div>
          <img src={`http://localhost:8080${user.avatar}`} alt="Avatar" />
          <p>Username: {user.username}</p>
          <p>Email: {user.email}</p>
          <p>Verified: {user.email_verified ? 'Yes' : 'No'}</p>
          
          {/* OAuth user indicator */}
          {user.is_oauth_user && (
            <p className="info">
               Logged in with {user.social_accounts?.[0]?.provider || 'OAuth'}
            </p>
          )}
          
          {/* Password change - only for non-OAuth users */}
          {!user.is_oauth_user && (
            <button onClick={() => {
              const current = prompt('Current password:');
              const newPass = prompt('New password:');
              if (current && newPass) changePassword(current, newPass);
            }}>
              Change Password
            </button>
          )}
          
          {/* Email change - only for non-OAuth users */}
          {!user.is_oauth_user && (
            <button onClick={() => {
              const newEmail = prompt('New email:');
              const password = prompt('Your password:');
              if (newEmail && password) changeEmail(newEmail, password);
            }}>
              Change Email
            </button>
          )}
        </div>
      )}
    </div>
  );
}

API Özeti

Endpoint Method ıklama Auth Required
/v1/profile GET Profil bilgilerini getir
/v1/profile PUT Profil güncelle (username, avatar)
/v1/profile/password PUT Şifre değiştir
/v1/profile/email PUT Email değiştir

Güvenlik Notları

İyi Pratikler:

  • Şifre değiştirirken mevcut şifre doğrulanır
  • Email değiştirirken doğrulama email'i gönderilir
  • Avatar dosya boyutu sınırlandırılmıştır (max 5MB)
  • Tüm endpoint'ler authentication gerektirir

⚠️ Dikkat Edilmesi Gerekenler:

  • OAuth kullanıcıları (Google/GitHub) şifre ve email değiştiremez
  • OAuth kullanıcıları sadece username ve avatar değiştirebilir
  • Frontend'de is_oauth_user flag'ini kontrol edin
  • Şifre değiştirme butonu OAuth kullanıcılarına gösterilmemeli
  • Email değiştirme butonu OAuth kullanıcılarına gösterilmemeli
  • Email değiştirildiğinde yeniden doğrulama gerekir
  • Şifre minimum 6 karakter olmalı
  • Avatar sadece resim formatları kabul edilir

OAuth Kullanıcı Kısıtlamaları

Özellik Email/Password Kullanıcı OAuth Kullanıcı (Google/GitHub)
Profil Görüntüleme Evet Evet
Username Değiştirme Evet Evet
Avatar Yükleme Evet Evet
Şifre Değiştirme Evet Hayır
Email Değiştirme Evet Hayır

Önemli: Frontend'de is_oauth_user field'ını kontrol ederek UI'ı buna göre düzenleyin.


Test Komutları

# Login ve token al
TOKEN=$(curl -s -X POST http://localhost:8080/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email":"user@example.com","password":"password123"}' | jq -r '.access_token')

# Profil bilgilerini getir
curl -X GET "http://localhost:8080/v1/profile" \
  -H "Authorization: Bearer $TOKEN" | jq '.'

# Username güncelle
curl -X PUT "http://localhost:8080/v1/profile" \
  -H "Authorization: Bearer $TOKEN" \
  -F "user_name=New Name"

# Avatar yükle
curl -X PUT "http://localhost:8080/v1/profile" \
  -H "Authorization: Bearer $TOKEN" \
  -F "avatar=@./photo.jpg"

# Şifre değiştir
curl -X PUT "http://localhost:8080/v1/profile/password" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"current_password":"old123","new_password":"new456"}'

# Email değiştir
curl -X PUT "http://localhost:8080/v1/profile/email" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"new_email":"new@email.com","password":"password123"}'

Özet

🎯 Özellikler:

  • Profil bilgilerini görüntüleme
  • Kullanıcı adı güncelleme
  • Avatar yükleme (max 5MB)
  • Şifre değiştirme (mevcut şifre doğrulaması ile)
  • Email değiştirme (yeniden doğrulama ile)

📊 Kullanım:

  • Her kullanıcı kendi profilini yönetebilir
  • OAuth kullanıcıları şifre değiştiremez
  • Email değişikliği doğrulama gerektirir
  • Avatar otomatik optimize edilir