Kimlik Doğrulama
Token'lar, giriş, yenileme, doğrulama ve çıkış.
ErtisAuth iki tür çağıranın kimliğini doğrular:
- Kullanıcılar bir username ya da e-posta adresi ve şifreyle (ya da bir harici sağlayıcı üzerinden veya cihaz kodu akışıyla) giriş yapar ve bir çift Bearer token alır: bir access token ve bir refresh token.
- Uygulamalar her istekte id'leri ve secret'larından oluşan bir Basic token gönderir. Giriş yapmaları gereken bir şey yoktur.
İkisi de Authorization header'ında gönderilir:
Authorization: Bearer eyJhbGciOiJIUzI1NiIs…
Authorization: Basic 66f1c0d2a4b5c6d7e8f90126:<application_secret>Endpoint'ler#
| Metot | Route | Açıklama | Kimlik doğrulama |
|---|---|---|---|
POST | /generate-token | Giriş yapma ya da scoped token alma | yok / Bearer |
GET POST | /refresh-token | Refresh token ile yeni bir token çifti alma | refresh token |
GET POST | /verify-token | Bir token'ı kontrol etme | herhangi bir token |
GET POST | /revoke-token | Çıkış yapma | access ya da refresh token |
GET | /me, /whoami | Token'ın sahibini alma | Bearer / Basic |
POST | /oauth/{slug}/login | Harici bir sağlayıcıyla giriş yapma | yok |
POST | /verify-otp | Tek kullanımlık şifreyi bir sıfırlama token'ıyla değiştirme | yok |
Son ikisi Harici Kimlik Sağlayıcılar ve Hesap Kurtarma sayfalarında anlatılır.
Token'lar#
Access token#
Membership'in secret_key anahtarıyla HMAC-SHA256 kullanılarak imzalanmış bir JWT. Claim'leri:
| Claim | Değer |
|---|---|
sub | Kullanıcının id'si |
prn | Membership'in id'si |
jti | Benzersiz bir token id'si |
iss | Membership'in adı |
aud | Membership'in slug'ı |
given_name, family_name | Kullanıcının adı ve soyadı |
unique_name | Username |
email | E-posta adresi |
scope | Boşlukla ayrılmış scope'lar (yalnızca scoped token'larda) |
iat, nbf, exp | Üretilme, geçerlilik başlangıcı ve bitiş zamanları |
Geçerlilik süresi membership'in expires_in değeridir (saniye cinsinden).
Bu claim'leri okumak için token'ı çözebilirsiniz, ama bir token'ı yalnızca imzası geçerli diye geçerli saymayın: bir token süresi dolmadan iptal edilebilir, kullanıcı da devre dışı bırakılabilir. /verify-token ya da /me endpoint'ini çağırın veya bunu sizin yerinize yapan SDK'yı kullanın.
Refresh token#
Access token gibi bir JWT'dir; ek olarak bir refresh_token: true claim'i taşır ve membership'in refresh_token_expires_in süresi boyunca geçerlidir. Yalnızca yeni bir token çifti almak için kullanılabilir: access token olarak kullanılırsa 401 InvalidToken ile reddedilir.
Basic token#
<application_id>:<secret>. Süresi dolmaz; secret yenilendiğinde ya da uygulama silindiğinde çalışmaz hale gelir. Her sorun (bilinmeyen uygulama, yanlış secret, bilinmeyen membership) aynı şekilde, 401 InvalidToken olarak bildirilir; böylece uygulama id'leri yoklanamaz.
Giriş yapma#
POST /generate-token| Header | Zorunlu | Açıklama |
|---|---|---|
X-Ertis-Alias | evet | Membership id'si (Membership ya da MembershipId da çalışır) |
X-IpAddress | hayır | Son kullanıcının IP adresi; oturumla birlikte saklanır |
X-UserAgent | hayır | Son kullanıcının user agent'ı; oturumla birlikte saklanır |
{
"username": "ada@example.com",
"password": "<password>"
}username alanı username'i de e-posta adresini de kabul eder.
Yanıt 201 Created
{
"token_type": "Bearer",
"access_token": "eyJhbGciOiJIUzI1NiIs…",
"expires_in": 3600,
"refresh_token": "eyJhbGciOiJIUzI1NiIs…",
"refresh_token_expires_in": 86400,
"created_at": "2026-01-01T12:00:00Z"
}expires_in ve refresh_token_expires_in saniye cinsindendir ve created_at anından itibaren sayılır.
Hatalar
| Durum | Kod | Ne zaman |
|---|---|---|
400 | MembershipIdRequired | X-Ertis-Alias eksik |
401 | InvalidCredentials | Bilinmeyen kullanıcı ya da yanlış şifre |
401 | UserInactive | Şifre doğru ama hesap aktif değil (henüz aktifleştirilmemiş ya da dondurulmuş) |
404 | MembershipNotFound | Membership yok |
Kullanıcılarınızı korumak için:
- bilinmeyen bir kullanıcı ile yanlış bir şifre aynı yanıtı verir ve yaklaşık aynı sürede yanıtlanır; böylece saldırganlar hangi hesapların var olduğunu öğrenemez;
- hesap durumu (
UserInactive) yalnızca doğru şifreyi bilen çağıranlara gösterilir.
Başarılı bir giriş, bir TokenGenerated olayı ve bir aktif token kaydeder.
Backend'inizden giriş yapma#
Backend'iniz kullanıcıları onlar adına giriş yaptırıyorsa (sunucu tarafında render edilen bir web uygulaması, bir BFF), oturumların nereden geldiği görünsün diye son kullanıcının bilgilerini iletin:
curl -X POST https://auth.example.com/generate-token \
-H 'X-Ertis-Alias: <membership_id>' \
-H 'X-IpAddress: 203.0.113.42' \
-H 'X-UserAgent: Mozilla/5.0 (Macintosh; Intel Mac OS X 14_0) …' \
-H 'Content-Type: application/json' \
-d '{ "username": "ada", "password": "<password>" }'Scoped token'lar#
Scoped token, kullanıcısının yapabildiklerinin yalnızca bir kısmını yapabilen bir access token'dır. Bir token'ı daha az güvenilen bir tarafa verirken kullanın: bir tarayıcı eklentisi, üçüncü taraf bir entegrasyon, kısa ömürlü bir iş.
Kimlik bilgisi göndermeden, geçerli bir access token ve scopes listesiyle isteyin:
curl -X POST https://auth.example.com/generate-token \
-H 'X-Ertis-Alias: <membership_id>' \
-H 'Authorization: Bearer <access_token>' \
-H 'Content-Type: application/json' \
-d '{ "scopes": [ "users.read", "roles.read" ] }'Yanıt 201 Created
{
"token_type": "Bearer",
"access_token": "eyJhbGciOiJIUzI1NiIs…",
"expires_in": 43200,
"created_at": "2026-01-01T12:00:00Z",
"scopes": [ "users.read", "roles.read" ]
}Kurallar:
- Scope'lar yetki biçimini kullanır (
users.read,*.users.read.*…). - Kullanıcı istenen her yetkiye sahip olmalıdır; aksi halde istek
400 UserHasNoPermissionForThisScopeile başarısız olur. Geçersiz bir ifade400 InvalidScope, boş bir liste400 ScopeRequiredile başarısız olur. - Bir scoped token yalnızca daraltılabilir: bir scoped token, daha az scope'lu yeni bir token isteyebilir, daha fazlasıyla asla.
- Scoped token ile yapılan bir isteğe hem kullanıcının yetkileri hem de token'ın scope'ları izin vermelidir. Scope'lar son kapıdır: kullanıcının sahip olmadığı hiçbir şeyi vermezler.
- Geçerlilik süresi membership'in
scoped_token_expires_indeğeridir; ayarlanmamışsa 12 saattir. - Refresh token döndürülmez.
Token yenileme#
Access token'ın süresi dolmadan önce refresh token'ı yeni bir token çiftiyle değiştirin.
GET /refresh-token
Authorization: Bearer <refresh_token>ya da refresh token gövdedeyken:
POST /refresh-token
Content-Type: application/json
{ "token": "<refresh_token>" }| Query parametresi | Varsayılan | Açıklama |
|---|---|---|
revoke | true | Kullanılan refresh token'ı iptal eder; böylece yalnızca bir kez çalışır. Kullanılabilir kalması için revoke=false gönderin. |
Yanıt 201 Created: giriş yanıtıyla aynı biçimde yeni bir token çifti. Yenilenen token orijinalinin scope'larını korur.
Hatalar
| Durum | Kod | Ne zaman |
|---|---|---|
400 | RefreshTokenRequired | Header'da ya da gövdede token yok |
401 | TokenIsNotRefreshable | Token bir refresh token değil, access token |
401 | RefreshTokenWasExpired | Refresh token'ın süresi dolmuş: kullanıcı yeniden giriş yapmalı |
401 | RefreshTokenWasRevoked | Refresh token zaten kullanılmış ya da iptal edilmiş |
401 | UserInactive | Kullanıcı bu arada devre dışı bırakılmış |
Token doğrulama#
Bir Bearer ya da Basic token'ı kontrol eder: imza, süre, iptal durumu ve kullanıcısının ya da uygulamasının hâlâ var ve aktif olup olmadığı.
GET /verify-token
Authorization: Bearer <token>ya da
POST /verify-token
Content-Type: application/json
{ "token": "Bearer <token>" }Gövdede token, türüyle birlikte verilir (Bearer … ya da Basic …).
Bir Bearer token için yanıt 200 OK:
{
"verified": true,
"token": "eyJhbGciOiJIUzI1NiIs…",
"token_kind": "access_token",
"remaining_time": 2875
}| Alan | Açıklama |
|---|---|
verified | Token'ın geçerli olup olmadığı |
token_kind | access_token ya da refresh_token |
remaining_time | Token'ın süresinin dolmasına kalan saniye |
Bir Basic token için yanıtta yalnızca verified ve token bulunur.
Geçersiz bir token sebebiyle birlikte 401 döner:
| Kod | Ne zaman |
|---|---|
InvalidToken | Hatalı biçim, yanlış imza, bilinmeyen membership ya da bir sıfırlama/aktivasyon token'ı |
TokenWasExpired | Süresi dolmuş |
TokenWasRevoked | İptal edilmiş (çıkış yapıldı, şifre değişti, kullanıcı donduruldu…) |
UserInactive | Kullanıcı devre dışı bırakılmış |
Token'ın sahibini alma#
GET /me
Authorization: Bearer <access_token>/whoami aynı endpoint'in başka bir adıdır.
- Bearer token ile yanıt, kullanıcı tipinin özel alanları dahil eksiksiz kullanıcıdır (şifre hash'i asla dahil değildir).
- Basic token ile yanıt uygulamadır (secret'ı asla dahil değildir).
{
"_id": "66f1c0d2a4b5c6d7e8f90124",
"username": "ada",
"firstname": "Ada",
"lastname": "Lovelace",
"email_address": "ada@example.com",
"role": "admin",
"user_type": "employee",
"permissions": [],
"forbidden": [],
"is_active": true,
"source_provider": "ErtisAuth",
"membership_id": "66f1c0d2a4b5c6d7e8f90123",
"sys": { "created_at": "2026-01-01T12:00:00Z", "created_by": "system" }
}Çıkış yapma#
Bir token'ı iptal eder. Bir token çifti birlikte iptal edilir: access token'ı iptal etmek onun refresh token'ını da iptal eder, tersi de geçerlidir.
GET /revoke-token
Authorization: Bearer <access_token>ya da
POST /revoke-token
Content-Type: application/json
{ "token": "<access_token>" }| Query parametresi | Varsayılan | Açıklama |
|---|---|---|
logout-all | false | true, kullanıcının her cihazdaki tüm token'larını iptal eder |
Token iptal edildiyse yanıt 204 No Content; edilemediyse (zaten iptal edilmiş, süresi dolmuş, geçersiz) 401.
İptal edilen token'lar Oturumlar sayfasında listelenir ve bir TokenRevoked olayı kaydeder.
Token'ların iptal edildiği diğer durumlar#
| İşlem | Etki |
|---|---|
| Şifre değiştirme | Kullanıcının tüm token'ları iptal edilir; kullanıcı kendi şifresini değiştirdiyse bunu yaptığı oturum hariç |
| Sıfırlama token'ıyla yeni şifre belirleme | Kullanıcının tüm token'ları iptal edilir |
| Kullanıcıyı dondurma | Kullanıcının tüm token'ları iptal edilir ve kullanıcı giriş yapamaz |
| Uygulama secret'ını yenileme | Eski Basic token hemen çalışmaz hale gelir |
Önerilen istemci akışı#
/generate-tokenile giriş yapın ve iki token'ı da saklayın.- Her istekle access token'ı gönderin.
expires_indolmadan kısa bir süre önce ya da bir istek401 TokenWasExpireddöndüğünde/refresh-tokenendpoint'ini çağırın ve iki token'ı da değiştirin.- Yenileme
401ile başarısız olursa kullanıcıyı giriş sayfasına gönderin. - Çıkışta
/revoke-tokenendpoint'ini çağırın ("her yerden çıkış yap" içinlogout-all=trueile).
Dokümantasyonda bir hata mı buldunuz? Issue açın