ErtisAuth

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:

http
Authorization: Bearer eyJhbGciOiJIUzI1NiIs…
Authorization: Basic 66f1c0d2a4b5c6d7e8f90126:<application_secret>
Not: HTTP Basic kimlik doğrulamasından farklı olarak Basic token base64 ile kodlanmış değildir: uygulama id'si ile secret'ın iki nokta üst üsteyle ayrılmış, düz metin halidir. Her zaman HTTPS kullanın.

Endpoint'ler#

MetotRouteAçıklamaKimlik doğrulama
POST/generate-tokenGiriş yapma ya da scoped token almayok / Bearer
GET POST/refresh-tokenRefresh token ile yeni bir token çifti almarefresh token
GET POST/verify-tokenBir token'ı kontrol etmeherhangi bir token
GET POST/revoke-tokenÇıkış yapmaaccess ya da refresh token
GET/me, /whoamiToken'ın sahibini almaBearer / Basic
POST/oauth/{slug}/loginHarici bir sağlayıcıyla giriş yapmayok
POST/verify-otpTek kullanımlık şifreyi bir sıfırlama token'ıyla değiştirmeyok

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:

ClaimDeğer
subKullanıcının id'si
prnMembership'in id'si
jtiBenzersiz bir token id'si
issMembership'in adı
audMembership'in slug'ı
given_name, family_nameKullanıcının adı ve soyadı
unique_nameUsername
emailE-posta adresi
scopeBoş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#

http
POST /generate-token
HeaderZorunluAçıklama
X-Ertis-AliasevetMembership id'si (Membership ya da MembershipId da çalışır)
X-IpAddresshayırSon kullanıcının IP adresi; oturumla birlikte saklanır
X-UserAgenthayırSon kullanıcının user agent'ı; oturumla birlikte saklanır
json
{
	"username": "ada@example.com",
	"password": "<password>"
}

username alanı username'i de e-posta adresini de kabul eder.

Yanıt 201 Created

json
{
	"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

DurumKodNe zaman
400MembershipIdRequiredX-Ertis-Alias eksik
401InvalidCredentialsBilinmeyen kullanıcı ya da yanlış şifre
401UserInactiveŞifre doğru ama hesap aktif değil (henüz aktifleştirilmemiş ya da dondurulmuş)
404MembershipNotFoundMembership 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:

shell
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:

shell
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

json
{
	"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 UserHasNoPermissionForThisScope ile başarısız olur. Geçersiz bir ifade 400 InvalidScope, boş bir liste 400 ScopeRequired ile 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_in değ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.

http
GET /refresh-token
Authorization: Bearer <refresh_token>

ya da refresh token gövdedeyken:

http
POST /refresh-token
Content-Type: application/json

{ "token": "<refresh_token>" }
Query parametresiVarsayılanAçıklama
revoketrueKullanı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

DurumKodNe zaman
400RefreshTokenRequiredHeader'da ya da gövdede token yok
401TokenIsNotRefreshableToken bir refresh token değil, access token
401RefreshTokenWasExpiredRefresh token'ın süresi dolmuş: kullanıcı yeniden giriş yapmalı
401RefreshTokenWasRevokedRefresh token zaten kullanılmış ya da iptal edilmiş
401UserInactiveKullanıcı bu arada devre dışı bırakılmış
Not: yenileme önceki access token'ı iptal etmez; o token süresi dolana kadar geçerli kalır. Hemen çalışmaz hale gelmesi gerekiyorsa açıkça iptal edin.

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ığı.

http
GET /verify-token
Authorization: Bearer <token>

ya da

http
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:

json
{
	"verified": true,
	"token": "eyJhbGciOiJIUzI1NiIs…",
	"token_kind": "access_token",
	"remaining_time": 2875
}
AlanAçıklama
verifiedToken'ın geçerli olup olmadığı
token_kindaccess_token ya da refresh_token
remaining_timeToken'ı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:

KodNe zaman
InvalidTokenHatalı biçim, yanlış imza, bilinmeyen membership ya da bir sıfırlama/aktivasyon token'ı
TokenWasExpiredSüresi dolmuş
TokenWasRevokedİptal edilmiş (çıkış yapıldı, şifre değişti, kullanıcı donduruldu…)
UserInactiveKullanıcı devre dışı bırakılmış

Token'ın sahibini alma#

http
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).
json
{
	"_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.

http
GET /revoke-token
Authorization: Bearer <access_token>

ya da

http
POST /revoke-token
Content-Type: application/json

{ "token": "<access_token>" }
Query parametresiVarsayılanAçıklama
logout-allfalsetrue, 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#

İşlemEtki
Şifre değiştirmeKullanı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 belirlemeKullanıcının tüm token'ları iptal edilir
Kullanıcıyı dondurmaKullanıcının tüm token'ları iptal edilir ve kullanıcı giriş yapamaz
Uygulama secret'ını yenilemeEski Basic token hemen çalışmaz hale gelir
  1. /generate-token ile giriş yapın ve iki token'ı da saklayın.
  2. Her istekle access token'ı gönderin.
  3. expires_in dolmadan kısa bir süre önce ya da bir istek 401 TokenWasExpired döndüğünde /refresh-token endpoint'ini çağırın ve iki token'ı da değiştirin.
  4. Yenileme 401 ile başarısız olursa kullanıcıyı giriş sayfasına gönderin.
  5. Çıkışta /revoke-token endpoint'ini çağırın ("her yerden çıkış yap" için logout-all=true ile).

Dokümantasyonda bir hata mı buldunuz? Issue açın