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

202 lines
7.4 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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
```