ErtisAuth

Hesap Kurtarma ve Aktivasyon

Aktivasyon e-postaları, şifre sıfırlama ve tek kullanımlık şifreler.

Bu sayfa, kullanıcıların e-posta adreslerinin kendilerine ait olduğunu kanıtlamalarını ve hesaplarına geri dönmelerini sağlayan akışları anlatır:

  • Hesap aktivasyonu: yeni kullanıcılar giriş yapabilmeden önce e-posta adreslerini onaylar.
  • Şifre sıfırlama: şifresini unutan kullanıcılar e-postayla bir sıfırlama bağlantısı alır.
  • Tek kullanımlık şifreler: kullanıcılar sizin seçtiğiniz bir kanaldan (SMS, çağrı merkezi…) kısa bir kod alır ve bunu bir şifre sıfırlamayla değiştirir.

Üçü de ErtisAuth'u çağıran, size ait bir sayfa (bir aktivasyon sayfası, bir şifre sıfırlama sayfası) ve onun backend'i ile sona erer. ErtisAuth bu sayfaları barındırmaz.

Aktivasyon ve sıfırlama e-postaları sayfanıza bir bağlantı içerir. Sayfanın URL'sini X-Host header'ında verirsiniz; ErtisAuth da buna kod içeren bir query parametresi ekler:

AkışBağlantı
Aktivasyon{X-Host}?uat=<code>
Şifre sıfırlama{X-Host}?rpt=<code>

Örneğin X-Host: https://app.example.com/reset-password ile sıfırlama e-postası https://app.example.com/reset-password?rpt=NjZmMWMw… adresine bağlantı verir.

Kod, <membership_id>:<token> değerinin base64 halidir. Onu opak bir değer olarak ele alın: sayfanız kodu query string'den okur ve ErtisAuth'a değiştirmeden geri gönderir.

Kodlar tek kullanımlık ve kısa ömürlüdür; access token olarak kullanılamazlar.

Bu endpoint'leri kim çağırır#

Sayfanızdaki kişi giriş yapmamış olduğu için bu akışların endpoint'leri diğer endpoint'ler gibi korunur (yetkiler aşağıda). Onları sayfanızın backend'inden, bir uygulamanın Basic token'ıyla çağırın ve o uygulamanın rolüne yalnızca akışların ihtiyaç duyduğunu verin:

json
{
	"name": "Account Pages",
	"slug": "account-pages",
	"permissions": [ "users.read", "users.update", "users.create" ]
}

Uygulamanın secret'ını asla tarayıcıya koymayın.

Hesap aktivasyonu#

Bir membership'in user_activation değeri active olduğunda yeni kullanıcılar aktif olmadan oluşturulur ve aktivasyon e-postalarındaki bağlantıya tıklayana kadar giriş yapamazlar (401 UserInactive).

Kurulum#

  1. Membership'e bir mail sağlayıcısı ekleyin (mail_providers; bkz. Membership'ler).
  2. Adı tam olarak User Activation olan, UserCreated olayı için ve active durumunda bir mail hook oluşturun. Şablonunda {{activationLink}} kullanın:
    json
    {
    	"name": "User Activation",
    	"event": "UserCreated",
    	"status": "active",
    	"mailProvider": "company-smtp",
    	"fromName": "My Company",
    	"fromAddress": "no-reply@example.com",
    	"sendToUtilizer": false,
    	"recipients": [ { "displayName": "{{user.firstname}}", "emailAddress": "{{user.email_address}}" } ],
    	"mailSubject": "Activate your account",
    	"mailTemplate": "<p>Hi {{user.firstname}},</p><p><a href=\"{{activationLink}}\">Activate your account</a></p>"
    }
    Şablon user (yeni kullanıcı) ve activationLink değerlerini alır.
  3. Membership'te user_activation değerini active yapın.

Mail sağlayıcısı ya da aktivasyon mail hook'u olmadan kullanıcı oluşturma, hiçbir şey oluşturulmadan 501 NotDefinedAnyMailProvider ya da 501 ActivationMailHookWasNotDefined ile başarısız olur.

Akış#

  1. Kullanıcıyı X-Host header'ı aktivasyon sayfanızı gösterecek şekilde oluşturun:
    http
    POST /memberships/{membershipId}/users
    X-Host: https://app.example.com/activate
    Kullanıcı aktif olmadan oluşturulur ve aktivasyon e-postası kuyruğa alınır. X-Host eksikse kullanıcı yine oluşturulur ama e-posta gönderilmez; e-postayı daha sonra yeniden gönderin.
  2. Kullanıcı bağlantıya tıklar ve https://app.example.com/activate?uat=<code> adresine gelir.
  3. Backend'iniz hesabı aktifleştirir:
    http
    GET /memberships/{membershipId}/users/activation?uat=<code>
    Authorization: Basic <application_id>:<secret>
    Yetki: users.update. Yanıt 200 OK, aktifleştirilen kullanıcıyla birlikte.

Aktivasyon kodu 72 saat geçerlidir ve yalnızca bir kez kullanılabilir. Kullanıcı bu arada değiştirilirse, örneğin dondurulursa, kod da çalışmaz hale gelir.

HataNe zaman
401 InvalidTokenKod hatalı biçimde, süresi dolmuş, zaten kullanılmış ya da başka bir membership'e ait
400 UserAlreadyActiveKullanıcı zaten aktif

Aktivasyon e-postasını yeniden gönderme#

http
POST /memberships/{membershipId}/users/resend-activation-mail
X-Host: https://app.example.com/activate
Content-Type: application/json

{ "email_address": "ada@example.com" }

Yetki: users.create. Yanıt 200 OK:

json
{ "emailAddress": "ada@example.com" }
HataNe zaman
400 HostRequired, 400 EmailAddressRequiredZorunlu bir değer eksik
400 UserAlreadyActiveAktifleştirilecek bir şey yok
404 UserNotFoundBu e-posta adresine sahip kullanıcı yok
501 NotDefinedAnyMailProvider, 501 ActivationMailHookWasNotDefinedE-posta gönderilemiyor

E-posta olmadan aktifleştirme#

Bir yönetici bir kullanıcıyı GET /users/{id}/activate ile doğrudan aktifleştirebilir.

Şifre sıfırlama#

Kurulum#

  1. Membership'e bir mail sağlayıcısı ekleyin.
  2. Adı tam olarak Reset Password olan, UserPasswordReset olayı için ve active durumunda bir mail hook oluşturun. Şablonunda {{resetPasswordLink}} kullanın:
    json
    {
    	"name": "Reset Password",
    	"event": "UserPasswordReset",
    	"status": "active",
    	"mailProvider": "company-smtp",
    	"fromName": "My Company",
    	"fromAddress": "no-reply@example.com",
    	"recipients": [ { "displayName": "{{user.firstname}}", "emailAddress": "{{user.email_address}}" } ],
    	"mailSubject": "Reset your password",
    	"mailTemplate": "<p>Hi {{user.firstname}},</p><p><a href=\"{{resetPasswordLink}}\">Choose a new password</a>. The link expires soon.</p>"
    }
    Şablon user ve resetPasswordLink değerlerini alır.
  3. İsterseniz membership'te reset_password_token_expires_in değerini ayarlayın (varsayılan olarak 2 saat).

1. Sıfırlamayı isteyin#

"Şifremi unuttum" sayfanızın backend'i şunu çağırır:

http
POST /memberships/{membershipId}/users/reset-password
Authorization: Basic <application_id>:<secret>
X-Host: https://app.example.com/reset-password
Content-Type: application/json

{ "email_address": "ada@example.com" }

Yetki: users.update. Yanıt 200 OK:

json
{
	"message": "Reset token generated",
	"expiresIn": 7200
}

E-posta kuyruğa alınır ve bir UserPasswordReset olayı kaydedilir.

HataNe zaman
400 HostRequired, 400 EmailAddressRequiredZorunlu bir değer eksik
401 UserInactiveHesap aktif değil ya da dondurulmuş: bu yolla kurtarılamaz
404 UserNotFoundBu e-posta adresine sahip kullanıcı yok
501 NotDefinedAnyMailProvider, 501 ResetPasswordMailHookWasNotDefinedE-posta gönderilemiyor
Not: bilinmeyen bir e-posta adresi 404 döner. Hangi adreslerin hesabı olduğunu açığa vurmamak için iki durumda da kişiye aynı mesajı gösterin ("Böyle bir hesap varsa size bir e-posta gönderdik").

Kullanıcı https://app.example.com/reset-password?rpt=<code> adresini açtığında, formu göstermeden önce kodu kontrol edin:

http
GET /memberships/{membershipId}/users/verify-reset-token?token=<code>
Authorization: Basic <application_id>:<secret>

Yetki: users.read. Yanıt 200 OK:

json
{ "email_address": "ada@example.com" }

Geçersiz, süresi dolmuş ya da kullanılmış bir kod 401 InvalidToken döner.

3. Yeni şifreyi belirleyin#

http
POST /memberships/{membershipId}/users/set-password
Authorization: Basic <application_id>:<secret>
Content-Type: application/json

{
	"email_address": "ada@example.com",
	"reset_token": "<code>",
	"password": "<new password>"
}

email_address yerine username da gönderilebilir. Yetki: users.update. Yanıt 200 OK.

  • Kod o kullanıcıya ait olmalıdır.
  • Kod bir kez çalışır: şifreyi belirlemek onu geçersiz kılar.
  • Kullanıcının tüm cihazlardaki oturumları kapanır.
  • Bir UserPasswordChanged olayı kaydedilir.
HataNe zaman
400 ResetTokenRequired, 400 EmailAddressRequired, 400 PasswordRequiredZorunlu bir değer eksik
400 PasswordMinLengthRuleErrorŞifre 6 karakterden kısa
401 InvalidTokenKod geçersiz, süresi dolmuş, kullanılmış ya da başka bir kullanıcıya ait

Tek kullanımlık şifreler#

Tek kullanımlık şifreler (OTP), kullanıcıların hesaplarını e-posta olmadan kurtarmalarını sağlar: kısa bir kodu onlara kendiniz iletirsiniz, örneğin SMS ile ya da bir destek temsilcisi aracılığıyla; onlar da bu kodu bir şifre sıfırlamayla değiştirir.

Kurulum#

Membership'te otp_settings değerini ayarlayın:

json
"otp_settings": {
	"host": "https://app.example.com/reset-password",
	"policy": {
		"length": 6,
		"contains_letters": false,
		"contains_digits": true,
		"expires_in": 300,
		"max_attempts": 5
	}
}
AlanAçıklama
hostZorunlu. Kullanıcıların kodlarını girdiği sayfanın adresi; doğrulama isteği aynı değeri X-Host header'ında göndermelidir.
policy.lengthKodun karakter sayısı.
policy.contains_letters, policy.contains_digitsKodun karakter kümesi.
policy.expires_inKodun ve kodun karşılığında verilen sıfırlama token'ının (doğrulamadan itibaren sayılan) geçerlilik süresi, saniye cinsinden. Verilmezse 2 saat.
policy.max_attemptsKod silinmeden önce izin verilen yanlış deneme sayısı. Varsayılan 5, en az 1.

1. Bir kod üretin#

Backend'iniz (bir SMS servisi, bir destek aracı) bir kullanıcı için kod üretir:

http
GET /memberships/{membershipId}/users/{userId}/generate-otp
Authorization: Basic <application_id>:<secret>

Yetki: otp.create.{userId} (users değil, otp kaynağı). Yanıt 200 OK:

json
{
	"_id": "66f1c0d2a4b5c6d7e8f90150",
	"user_id": "66f1c0d2a4b5c6d7e8f90127",
	"email_address": "ada@example.com",
	"username": "ada",
	"password": "482913",
	"expires_in": 300,
	"created_at": "2026-01-01T12:00:00Z",
	"expire_time": "2026-01-01T12:05:00Z",
	"membership_id": "66f1c0d2a4b5c6d7e8f90123"
}

password alanı koddur. Kodu kullanıcıya iletin. Yalnızca bu yanıtta döner: ErtisAuth yalnızca anahtarlı bir hash'ini saklar. Yeni bir kod üretmek, kullanıcının önceki kodlarını siler.

Bu noktada henüz bir sıfırlama token'ı yoktur: token yalnızca kullanıcı kodu doğruladığında üretilir. Böylece kodları üreten servis kimsenin şifresini kendisi değiştiremez; veritabanını okuyabilen biri de değiştiremez.

HataNe zaman
400 OtpNotConfiguredYet, 400 OtpHostNotConfiguredYetMembership'in OTP ayarları yok
401 UserInactiveHesap aktif değil ya da dondurulmuş
404 UserNotFoundBilinmeyen kullanıcı

2. Kodu doğrulayın#

Kullanıcı sayfanızda username'ini (ya da e-posta adresini) ve kodu girer; sayfanız şunu çağırır:

http
POST /verify-otp
X-Ertis-Alias: <membership_id>
X-Host: https://app.example.com/reset-password
Content-Type: application/json

{
	"username": "ada",
	"password": "482913"
}

Token gerekmez. X-Host, membership'in otp_settings.host değerine eşit olmalıdır. Kodlar büyük/küçük harf ayrımı yapılmadan karşılaştırılır.

Yanıt 200 OK: şu anda üretilen bir sıfırlama token'ı. Geçerlilik süresi (expires_in) bu andan itibaren başlar.

json
{
	"reset_token": "NjZmMWMwZDJhNGI1YzZkN2U4ZjkwMTIzOmV5Smhi…",
	"expires_in": 300,
	"created_at": "2026-01-01T12:00:00Z"
}
Not: bu bir access token değildir. Yalnızca yeni bir şifre belirlemek için kullanılabilir.
HataNe zaman
400 OtpHostRequiredX-Host eksik
401 OtpHostMismatchX-Host, membership'in OTP host'u değil
401 InvalidCredentialsYanlış kod ya da bilinmeyen kullanıcı
401 OtpExpiredKod doğruydu ama süresi dolmuş
401 UserInactiveHesap, kod üretildikten sonra devre dışı bırakılmış ya da dondurulmuş

Bir kod bir kez kullanılabilir: başarılı bir doğrulama onu siler; bu yüzden aynı kodu tekrar doğrulamak 401 InvalidCredentials döner. Sıfırlama token'ı süresi dolana ya da kullanılana kadar geçerli kalır; yeniden doğrulamaya gerek yoktur.

Her yanlış kod başarısız bir deneme sayılır; max_attempts kadar başarısız denemeden sonra kod silinir ve yenisinin üretilmesi gerekir.

3. Yeni şifreyi belirleyin#

Önceki adımdaki reset_token ile POST /users/set-password endpoint'ini çağırın.

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