Files
goaresv3/belgeler/auth.md
Beyhan Oğur b6e74bd024 first commit
2026-04-26 21:41:46 +03:00

7.4 KiB
Raw Permalink Blame History

Kimlik Doğrulama Sistemi

Genel Bakış

Proje email + şifre tabanlı kimlik doğrulama kullanır. Başarılı girişte iki token döner:

Token Ömür Kullanım
access_token 15 dakika Her korumalı isteğe Authorization: Bearer başlığı
refresh_token 7 gün Süresi dolan access token'ı yenilemek için

Ek kural: Email doğrulaması tamamlanmadan login ve refresh işlemleri engellenir.

Algoritma: HS256 (HMAC-SHA256)


Akış Diyagramı

┌─────────┐        POST /api/v1/auth/register        ┌─────────┐
│ Client  │ ────────────────────────────────────► │ Server  │
│         │ ◄──── 201 { user_id } + verify mail   │         │
└─────────┘                                        └─────────┘

┌─────────┐        GET /api/v1/auth/verify-email      ┌─────────┐
│ Client  │ ── token linki ile ──────────────────► │ Server  │
│         │ ◄──── 200 email verified ────────────  │         │
└─────────┘                                        └─────────┘

┌─────────┐        POST /api/v1/auth/login            ┌─────────┐
│ Client  │ ── { email, password } ──────────────► │ Server  │
│         │ ◄── 200 { access_token,               │         │
│         │          refresh_token } ─────────────  └─────────┘
└─────────┘

┌─────────┐   GET /api/v1/me                          ┌─────────┐
│ Client  │ ── Authorization: Bearer <access> ───► │ Server  │
│         │ ◄── 200 { user_id, email, username }   │ (auth   │
└─────────┘                                        │ middleware)
                                                   └─────────┘

┌─────────┐   POST /api/v1/auth/refresh               ┌─────────┐
│ Client  │ ── { refresh_token } ────────────────► │ Server  │
│         │ ◄── 200 { access_token } ─────────────  └─────────┘
└─────────┘

Kayıt (Register)

Dosya: app/accounts/controllers/user.goRegister()

  1. JSON body doğrulanır (username min 3, email geçerli format, password min 8 karakter, confirm_password min 8 karakter).
  2. password ve confirm_password eşleşmesi kontrol edilir.
  3. Şifre bcrypt.DefaultCost ile hash'lenir.
  4. User kaydı veritabanına yazılır.
  5. Rastgele bir email doğrulama token'ı üretilir ve kullanıcıya yazılır.
  6. Kullanıcıya doğrulama maili gönderilir.
  7. email alanı unique index'li; duplicate durumunda 409 Conflict döner.

Not: Mail gönderimi başarısız olursa oluşturulan kullanıcı kaydı geri silinir.

// İstek
{
  "username": "ali",
  "email": "ali@ornek.com",
  "password": "gizli1234",
  "confirm_password": "gizli1234"
}

// Başarılı yanıt 201
{ "message": "user created. please verify your email", "user_id": 1 }

Email Doğrulama (VerifyEmail)

Dosya: app/accounts/controllers/user.goVerifyEmail()

  1. Query string içinden token alınır.
  2. Token ile kullanıcı bulunur.
  3. email_verified=true, email_verified_at=now, email_verify_token="" olarak güncellenir.
// Başarılı yanıt 200
{ "message": "email verified successfully" }

Giriş (Login)

Dosya: app/accounts/controllers/user.goLogin()

  1. Email ile kullanıcı aranır.
  2. email_verified kontrol edilir; doğrulanmamış hesaplara 403 dönülür.
  3. bcrypt.CompareHashAndPassword ile şifre doğrulanır.
  4. Her iki adımda da hata mesajı aynı tutulur — kullanıcı numaralandırma saldırısına karşı.
  5. Başarıda access + refresh token döner.
// İstek
{ "email": "ali@ornek.com", "password": "gizli1234" }

// Başarılı yanıt 200
{
  "access_token":  "eyJ...",
  "refresh_token": "eyJ...",
  "token_type":    "Bearer"
}

Token Yenileme (RefreshToken)

Dosya: app/accounts/controllers/user.goRefreshToken()

  1. Body'den refresh_token alınır.
  2. JWT_REFRESH_SECRET ile doğrulanır.
  3. Kullanıcının email_verified durumu kontrol edilir; doğrulanmamışsa 403 döner.
  4. Claims'ten user_id, email, username alanları kullanılarak yeni access token üretilir.
  5. Refresh token yenilenmez (sliding window değil, sabit pencere).
// İstek
{ "refresh_token": "eyJ..." }

// Başarılı yanıt 200
{ "access_token": "eyJ...", "token_type": "Bearer" }

Google Login (OAuth 2.0)

Dosya: app/accounts/controllers/user.goGoogleLogin() ve GoogleCallback()

Akış:

  1. GET /api/v1/auth/google/login
  2. Sunucu CSRF için state üretir, cookie'ye yazar ve auth_url döner.
  3. Client kullanıcıyı auth_url adresine yönlendirir.
  4. Google kullanıcıyı callback'e döndürür: GET /api/v1/auth/google/callback?state=...&code=...
  5. Sunucu state doğrular, code ile Google'dan token alır.
  6. Google userinfo verisi çekilir.
  7. Kullanıcı email'e göre bulunur/oluşturulur, SocialAccount(provider=google) kaydı bağlanır.
  8. Google ile gelen kullanıcı email'i doğrulanmış kabul edilir (email_verified=true).
  9. Yerel access_token + refresh_token üretilip döndürülür.

Yeni endpointler:

  • GET /api/v1/auth/google/login
  • GET /api/v1/auth/google/callback

GitHub Login (OAuth 2.0)

Dosya: app/accounts/controllers/user.goGitHubLogin() ve GitHubCallback()

Akış:

  1. GET /api/v1/auth/github/login
  2. Sunucu CSRF için state üretir, cookie'ye yazar ve auth_url döner.
  3. Client kullanıcıyı auth_url adresine yönlendirir.
  4. GitHub callback'e döndürür: GET /api/v1/auth/github/callback?state=...&code=...
  5. Sunucu state doğrular, code ile GitHub'dan token alır.
  6. GitHub profil/email bilgisi çekilir.
  7. Kullanıcı email'e göre bulunur/oluşturulur, SocialAccount(provider=github) kaydı bağlanır.
  8. GitHub ile gelen kullanıcı email'i doğrulanmış kabul edilir (email_verified=true).
  9. Yerel access_token + refresh_token üretilip döndürülür.

Yeni endpointler:

  • GET /api/v1/auth/github/login
  • GET /api/v1/auth/github/callback

Güvenlik Notları

  • Şifreler veritabanında asla düz metin tutulmaz; bcrypt hash'i saklanır.
  • Password alanı modelde json:"-" ile işaretlidir — API yanıtlarında görünmez.
  • Access ve refresh token farklı secret'larla imzalanır (JWT_SECRET / JWT_REFRESH_SECRET).
  • Production'da her iki secret'ın en az 32 karakter uzunluğunda, rastgele olması gerekir.
  • HTTPS zorunludur; token'lar aktarım sırasında şifrelenmez.
  • Register adımında şifre uyumsuzluğu için 400 Bad Request dönülür: password and confirm_password do not match.

Swagger

  • Swagger UI: /swagger/index.html
  • Doküman üretme komutu:
$(go env GOPATH)/bin/swag init -g main.go