first commit

This commit is contained in:
Beyhan Oğur
2026-04-26 21:41:46 +03:00
commit b6e74bd024
56 changed files with 16114 additions and 0 deletions

201
belgeler/auth.md Normal file
View File

@@ -0,0 +1,201 @@
# 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.go``Register()`
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.
```json
// İ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.go``VerifyEmail()`
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.
```json
// Başarılı yanıt 200
{ "message": "email verified successfully" }
```
---
## Giriş (`Login`)
**Dosya:** `app/accounts/controllers/user.go``Login()`
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.
```json
// İ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.go``RefreshToken()`
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).
```json
// İ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.go``GoogleLogin()` 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.go``GitHubLogin()` 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:
```bash
$(go env GOPATH)/bin/swag init -g main.go
```