7.4 KiB
7.4 KiB
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()
- JSON body doğrulanır (
usernamemin 3,emailgeçerli format,passwordmin 8 karakter,confirm_passwordmin 8 karakter). passwordveconfirm_passwordeşleşmesi kontrol edilir.- Şifre
bcrypt.DefaultCostile hash'lenir. Userkaydı veritabanına yazılır.- Rastgele bir email doğrulama token'ı üretilir ve kullanıcıya yazılır.
- Kullanıcıya doğrulama maili gönderilir.
emailalanı unique index'li; duplicate durumunda409 Conflictdö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.go → VerifyEmail()
- Query string içinden
tokenalınır. - Token ile kullanıcı bulunur.
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.go → Login()
- Email ile kullanıcı aranır.
email_verifiedkontrol edilir; doğrulanmamış hesaplara403dönülür.bcrypt.CompareHashAndPasswordile şifre doğrulanır.- Her iki adımda da hata mesajı aynı tutulur — kullanıcı numaralandırma saldırısına karşı.
- 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.go → RefreshToken()
- Body'den
refresh_tokenalınır. JWT_REFRESH_SECRETile doğrulanır.- Kullanıcının
email_verifieddurumu kontrol edilir; doğrulanmamışsa403döner. - Claims'ten
user_id,email,usernamealanları kullanılarak yeni access token üretilir. - 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.go → GoogleLogin() ve GoogleCallback()
Akış:
GET /api/v1/auth/google/login- Sunucu CSRF için
stateüretir, cookie'ye yazar veauth_urldöner. - Client kullanıcıyı
auth_urladresine yönlendirir. - Google kullanıcıyı callback'e döndürür:
GET /api/v1/auth/google/callback?state=...&code=... - Sunucu
statedoğrular,codeile Google'dan token alır. - Google
userinfoverisi çekilir. - Kullanıcı email'e göre bulunur/oluşturulur,
SocialAccount(provider=google)kaydı bağlanır. - Google ile gelen kullanıcı email'i doğrulanmış kabul edilir (
email_verified=true). - Yerel
access_token+refresh_tokenüretilip döndürülür.
Yeni endpointler:
GET /api/v1/auth/google/loginGET /api/v1/auth/google/callback
GitHub Login (OAuth 2.0)
Dosya: app/accounts/controllers/user.go → GitHubLogin() ve GitHubCallback()
Akış:
GET /api/v1/auth/github/login- Sunucu CSRF için
stateüretir, cookie'ye yazar veauth_urldöner. - Client kullanıcıyı
auth_urladresine yönlendirir. - GitHub callback'e döndürür:
GET /api/v1/auth/github/callback?state=...&code=... - Sunucu
statedoğrular,codeile GitHub'dan token alır. - GitHub profil/email bilgisi çekilir.
- Kullanıcı email'e göre bulunur/oluşturulur,
SocialAccount(provider=github)kaydı bağlanır. - GitHub ile gelen kullanıcı email'i doğrulanmış kabul edilir (
email_verified=true). - Yerel
access_token+refresh_tokenüretilip döndürülür.
Yeni endpointler:
GET /api/v1/auth/github/loginGET /api/v1/auth/github/callback
Güvenlik Notları
- Şifreler veritabanında asla düz metin tutulmaz; bcrypt hash'i saklanır.
Passwordalanı modeldejson:"-"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 Requestdö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